From 7e36e2f5355ab87f8946041d044b34cda01e2077 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Tue, 1 Apr 2008 10:53:23 +0100 Subject: [PATCH 0001/2509] [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 --- arch/arm/configs/ixp4xx_defconfig | 9 +- arch/arm/mach-ixp4xx/Kconfig | 9 + arch/arm/mach-ixp4xx/Makefile | 2 + arch/arm/mach-ixp4xx/fsg-pci.c | 71 +++++++ arch/arm/mach-ixp4xx/fsg-setup.c | 276 +++++++++++++++++++++++++ include/asm-arm/arch-ixp4xx/fsg.h | 50 +++++ include/asm-arm/arch-ixp4xx/hardware.h | 1 + include/asm-arm/arch-ixp4xx/irqs.h | 7 + 8 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-ixp4xx/fsg-pci.c create mode 100644 arch/arm/mach-ixp4xx/fsg-setup.c create mode 100644 include/asm-arm/arch-ixp4xx/fsg.h diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index efa0485d2f7..fc14932e3ab 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 e774447c059..db8b5fe06c0 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 c1956882c48..2e6bbf927a7 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 00000000000..f19f3f6feda --- /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 00000000000..0db3a909ae6 --- /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 00000000000..c0100cc7981 --- /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 73e8dc36f6a..fa723a62785 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 11801605047..674af4a8414 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 -- GitLab From e055d5bff318845f99c0fbf93245767fab8dce88 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Apr 2008 01:43:27 +0100 Subject: [PATCH 0002/2509] [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 --- arch/arm/Kconfig | 10 +------ arch/arm/Makefile | 2 -- arch/arm/mach-footbridge/Makefile | 2 -- arch/arm/mach-footbridge/co285.c | 39 ------------------------- arch/arm/mach-footbridge/common.c | 21 ------------- arch/arm/mach-footbridge/ebsa285-leds.c | 2 +- arch/arm/mach-footbridge/time.c | 3 +- include/asm-arm/arch-ebsa285/hardware.h | 26 ----------------- include/asm-arm/arch-ebsa285/memory.h | 19 ------------ include/asm-arm/arch-ebsa285/vmalloc.h | 4 --- 10 files changed, 3 insertions(+), 125 deletions(-) delete mode 100644 arch/arm/mach-footbridge/co285.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4039a133006..ab78d5c421f 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 1a4649667ec..79b8ca3400e 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 0694ad6b647..32f8609e4f8 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 4545576ad8d..00000000000 --- 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 ef29fc34ce6..b08ab507c05 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 a64e2222651..09c1fbc5187 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 5d02e95dede..d5cfcda385d 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 daad8ee2d19..74610c2c63d 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 cbd7ae64bcc..9019a3bf5ab 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 02598200997..e487d7e8c8a 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 -- GitLab From 205bee6ad804d7034773b5978c74dde495df2301 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 13:57:26 +0100 Subject: [PATCH 0003/2509] [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 --- arch/arm/Kconfig | 21 ---- arch/arm/configs/at91cap9adk_defconfig | 1 - arch/arm/configs/at91rm9200dk_defconfig | 1 - arch/arm/configs/at91rm9200ek_defconfig | 1 - arch/arm/configs/at91sam9260ek_defconfig | 1 - arch/arm/configs/at91sam9261ek_defconfig | 1 - arch/arm/configs/at91sam9263ek_defconfig | 1 - arch/arm/configs/at91sam9rlek_defconfig | 1 - arch/arm/configs/ateb9200_defconfig | 1 - arch/arm/configs/cm_x270_defconfig | 1 - arch/arm/configs/collie_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/ecbat91_defconfig | 1 - arch/arm/configs/em_x270_defconfig | 1 - arch/arm/configs/ep93xx_defconfig | 1 - arch/arm/configs/eseries_pxa_defconfig | 1 - arch/arm/configs/iop13xx_defconfig | 1 - arch/arm/configs/iop32x_defconfig | 1 - arch/arm/configs/iop33x_defconfig | 1 - arch/arm/configs/ixp2000_defconfig | 1 - arch/arm/configs/ixp23xx_defconfig | 1 - arch/arm/configs/kafa_defconfig | 1 - arch/arm/configs/kb9202_defconfig | 1 - arch/arm/configs/ks8695_defconfig | 1 - arch/arm/configs/lpd270_defconfig | 1 - arch/arm/configs/lpd7a404_defconfig | 1 - arch/arm/configs/netx_defconfig | 1 - arch/arm/configs/onearm_defconfig | 1 - arch/arm/configs/picotux200_defconfig | 1 - arch/arm/configs/pnx4008_defconfig | 1 - arch/arm/configs/realview-smp_defconfig | 1 - arch/arm/configs/realview_defconfig | 1 - arch/arm/configs/rpc_defconfig | 1 - arch/arm/configs/s3c2410_defconfig | 1 - arch/arm/configs/sam9_l9260_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm/configs/tct_hammer_defconfig | 1 - arch/arm/configs/trizeps4_defconfig | 1 - arch/arm/configs/versatile_defconfig | 1 - arch/arm/kernel/process.c | 4 +- arch/arm/kernel/time.c | 120 ----------------------- arch/arm/mach-omap1/pm.c | 7 -- arch/arm/mach-omap2/pm.c | 7 -- include/asm-arm/dyntick.h | 6 -- include/asm-arm/hw_irq.h | 11 --- include/asm-arm/mach/time.h | 22 ----- 46 files changed, 1 insertion(+), 235 deletions(-) delete mode 100644 include/asm-arm/dyntick.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..167824e24ed 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 e32e7364812..b8e73e95598 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 2dbbbc3d4ac..868fb7b9530 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 6e994f7820c..de43fc67561 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 f659c938473..2011adfa675 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 3802e85f748..4049768962d 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 32a0d74e0c8..fa1c5aecb5a 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 98e6746d02b..d8ec5f9ca6e 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 d846a492e5c..85c80f723d8 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 5cab08397ae..33b201c3b30 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 4264e273202..f7622e65816 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 e8980a9bb89..9b8748a8d9d 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 90ed214e367..cfeb817ad21 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 6bea0901bdf..d3114c23603 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 24a701ab33e..21aa013793c 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 ed487b90dbe..493ecee24f9 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 988b4d13e76..482e5706105 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 83f40d4041a..8612f58e105 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 917afb5ccfa..8b0098d19d0 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 f8f9793b526..84680db6c61 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 27cf022dd80..4a2f7b2372d 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 ae51a40db6f..6dd95a2c8d5 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 c16537d9d67..8e74c66f239 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 8ab21a0719e..6077f2cb88e 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 a3bf5833b87..1a38d8e3fe6 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 46a0f7fe1fa..7a2e932da1c 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 57f32f39d0f..0884f2370c3 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 650a248613e..418ca2febbe 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 95a22f51280..14826f0dabd 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 b5e11aa2e29..811b8f60d19 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 fc39ba1a89f..0c09b23167e 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 accbf529ce5..907e54344da 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 5ddecb9ddf0..f62d1817d2c 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 f8a1645b3d4..6d03763773b 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 484dc9739df..8688362bcf7 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 aa7a0117950..7d59fb1f1ce 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 576b8339f0d..07dfb98df4f 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 6db6392806f..8b7a431a8bf 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 48dca69adda..8355f88f729 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 46bf2ede612..199b3680118 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 b5867eca1d0..cc5145b28e7 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 e6c64e10b7e..742f79e73bd 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 aad781dcf1b..d6c9de82ca0 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 19fab2d2b76..00000000000 --- 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 98d594a973d..f1a08a50060 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 5dc357013b7..2fd36ea0130 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); -- GitLab From ee9c578527a93c66becb526c4a122c5358a959c5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 13:59:33 +0100 Subject: [PATCH 0004/2509] dyntick: Remove last reminants of dyntick support Remove the last reminants of dyntick support from the generic kernel. Signed-off-by: Russell King --- kernel/hrtimer.c | 2 +- kernel/sysctl.c | 12 ------------ kernel/timer.c | 10 +--------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 421be5fe5cc..543d9ca9b4f 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 d7ffdc59816..76426d93007 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 @@ -561,16 +559,6 @@ static struct ctl_table kern_table[] = { .mode = 0644, .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, diff --git a/kernel/timer.c b/kernel/timer.c index ceacc662657..ef3fa6906e8 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 -- GitLab From 150c9173031d43746d70582a17931350f3da8932 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 12 May 2008 17:37:21 +0100 Subject: [PATCH 0005/2509] 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 --- arch/sh/configs/landisk_defconfig | 1 - arch/sh/configs/lboxre2_defconfig | 1 - arch/sh/configs/se7705_defconfig | 1 - arch/sh/configs/se7712_defconfig | 1 - arch/sh/configs/se7750_defconfig | 1 - 5 files changed, 5 deletions(-) diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index f52db125432..38f934ab50c 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 9fa66d92a4e..b68b6cdbb78 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 84717d85486..490dcbc2ce3 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 240a1cef69a..2dd83af988f 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 c60b6fd4fc4..167786f9a9b 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 # -- GitLab From 88f85a55c0645c2b7e03bf34d2a90eddf6de34fa Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 12 May 2008 16:42:43 -0500 Subject: [PATCH 0006/2509] 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 --- fs/jfs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 0ba6778edaa..2aba8238681 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); -- GitLab From b2e03ca7485cac033a0667d9e45e28d32fdee9a5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 13 May 2008 08:22:10 -0500 Subject: [PATCH 0007/2509] JFS: switch to seq_files Signed-off-by: Alexey Dobriyan Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_debug.c | 62 ++++++++++++++++++--------------------- fs/jfs/jfs_debug.h | 10 +++---- fs/jfs/jfs_logmgr.c | 35 ++++++++++------------ fs/jfs/jfs_metapage.c | 36 +++++++++++------------ fs/jfs/jfs_txnmgr.c | 68 ++++++++++++++++++++----------------------- fs/jfs/jfs_xtree.c | 36 +++++++++++------------ 6 files changed, 114 insertions(+), 133 deletions(-) diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index bf6ab19b86e..6a73de84bce 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 044c1e654cc..eafd1300a00 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 325a9679b95..cd2ec2988b5 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 d1e64f2f2fc..854ff0ec574 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 e7c60ae6b5b..f26e4d03ada 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 5a61ebf2cbc..ae3acafb447 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 -- GitLab From 54ef0ec22a39071a4e7fbedd201cecac9ac6e8a7 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Fri, 2 May 2008 14:40:38 -0500 Subject: [PATCH 0008/2509] [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 --- drivers/net/Kconfig | 1 - drivers/net/Makefile | 1 - drivers/net/fec_8xx/Kconfig | 20 - drivers/net/fec_8xx/Makefile | 12 - drivers/net/fec_8xx/fec_8xx-netta.c | 151 ---- drivers/net/fec_8xx/fec_8xx.h | 220 ----- drivers/net/fec_8xx/fec_main.c | 1264 --------------------------- drivers/net/fec_8xx/fec_mii.c | 418 --------- 8 files changed, 2087 deletions(-) delete mode 100644 drivers/net/fec_8xx/Kconfig delete mode 100644 drivers/net/fec_8xx/Makefile delete mode 100644 drivers/net/fec_8xx/fec_8xx-netta.c delete mode 100644 drivers/net/fec_8xx/fec_8xx.h delete mode 100644 drivers/net/fec_8xx/fec_main.c delete mode 100644 drivers/net/fec_8xx/fec_mii.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d27f54a2df7..009e8fdcfe5 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 dcbfe842115..9010e58da0f 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 afb34ded26e..00000000000 --- 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 70c54f8c48e..00000000000 --- 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 79deee222e2..00000000000 --- 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 f3b1c6fbba8..00000000000 --- 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 ca8d2e83ab0..00000000000 --- 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 3b6ca29d31f..00000000000 --- 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); - - } -} -- GitLab 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: [PATCH 0009/2509] [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 --- arch/powerpc/sysdev/mpic_pasemi_msi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 33cbfb22ce3..68aff607667 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; } -- GitLab 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: [PATCH 0010/2509] [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 --- arch/powerpc/sysdev/mpic_u3msi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index 1d5a40899b7..6e2f8686fdf 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) { -- GitLab From 140b932f8cb6cced10b96860651a198b1b89cbb9 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 24 Apr 2008 23:16:00 +1000 Subject: [PATCH 0011/2509] [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 --- drivers/macintosh/macio_sysfs.c | 12 ++++++++++- drivers/of/device.c | 36 ++++++++++++++++++--------------- drivers/of/platform.c | 3 +++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 112e5ef728f..9e9453b5842 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 29681c4b700..8fbfeee53c1 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 ca09a63a64d..298de0f95d7 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); } -- GitLab From 7a10174eeafe737f3ccfcece5bdff749c3b044e0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 28 Apr 2008 17:30:37 +1000 Subject: [PATCH 0012/2509] [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 --- arch/powerpc/kernel/entry_32.S | 4 ++-- arch/powerpc/kernel/signal.c | 12 ++++++------ arch/powerpc/kernel/signal_32.c | 2 +- arch/ppc/kernel/entry.S | 4 ++-- include/asm-powerpc/thread_info.h | 17 +++++++++++++---- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0c8614d9875..3a05e9f93d4 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 a65a44fbe52..ad55488939c 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 ad6943468ee..4ae16d17980 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 5f3a5d068a5..fcd830a292e 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 d030f5ce39a..e079e81051f 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__ */ -- GitLab From 663276b7c6340e755ed62bed67a2b96f4fc3d513 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 30 Apr 2008 20:44:53 +1000 Subject: [PATCH 0013/2509] [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 --- arch/powerpc/kernel/head_booke.h | 2 +- include/asm-powerpc/ptrace.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index aefafc6330c..721faef8709 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 39023dde1cc..38d87e5e569 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__ -- GitLab From 683307da07afd3a7ee55269ee8cb70c8053b0923 Mon Sep 17 00:00:00 2001 From: Remi Machet Date: Thu, 1 May 2008 10:40:44 +1000 Subject: [PATCH 0014/2509] [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 --- arch/powerpc/sysdev/mv64x60_dev.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index a132e0de8ca..32e0ad0ebea 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); -- GitLab From 5f25f06529ecb4b20efc7ba00de599f5b9f4b63c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:07 +1000 Subject: [PATCH 0015/2509] [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 --- arch/powerpc/mm/init_32.c | 3 +-- include/asm-powerpc/system.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 1952b4d3fa7..45418590b6a 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 2b6559a6d11..df781adac6d 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; -- GitLab From 09de9ff872bca25ba717a7075c9ee49b1bdb56d2 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:07 +1000 Subject: [PATCH 0016/2509] [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 --- arch/powerpc/mm/hash_utils_64.c | 4 ++-- arch/powerpc/mm/init_64.c | 4 ++-- arch/powerpc/mm/stab.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 2b5a399f6fa..1a4b4b36b0c 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 c5ac532a016..1e52e97d740 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 efbbd13d93e..60e6032a808 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. -- GitLab From 572fb578de59efaaa8d197b0183db43b1128a06e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:08 +1000 Subject: [PATCH 0017/2509] [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 --- arch/powerpc/mm/hash_utils_64.c | 2 -- include/asm-powerpc/mmu-hash64.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1a4b4b36b0c..05f955f8df3 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 0dff7677604..f35d1e164da 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 -- GitLab From c884116ac375c5dd137109b58acaa9cf50164796 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:09 +1000 Subject: [PATCH 0018/2509] [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 --- arch/powerpc/mm/tlb_64.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c index e2d867ce1c7..509bc560159 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)) -- GitLab From 8fa29d22dcb2aec97f1a508cd3741c6e0b4a9434 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:11 +1000 Subject: [PATCH 0019/2509] [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 --- arch/powerpc/sysdev/mpic_msi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index d272a52ecd2..de3e5e8bc32 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) { -- GitLab From 7d9e793463d854073f5c0dedea991a5b63336d6a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:13 +1000 Subject: [PATCH 0020/2509] [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 --- include/asm-powerpc/xmon.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index 88320a05f0a..81477f24a18 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) { }; -- GitLab From af3b74df1b2fa4dbfb0534818167f6393f5ae7c7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:15 +1000 Subject: [PATCH 0021/2509] [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 --- arch/powerpc/platforms/chrp/setup.c | 7 ------- arch/powerpc/platforms/powermac/pic.c | 8 +------- include/asm-powerpc/xmon.h | 3 +++ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 116babbaaf8..1ba7ce5aafa 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 829b8b02527..6d149ae8ffa 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 81477f24a18..d83da3cbd08 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) { }; -- GitLab From 9f1067c2d98ac1c43f0c82892f5647774a6ac759 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:16 +1000 Subject: [PATCH 0022/2509] [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 --- arch/powerpc/xmon/xmon.c | 59 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1702de9395e..95f24c9822b 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)) -- GitLab From 1c8950ff87de950a3b6ccfb26650fc0a56278836 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:17 +1000 Subject: [PATCH 0023/2509] [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 --- arch/powerpc/xmon/xmon.c | 7 ++++++- drivers/char/hvc_console.c | 8 +------- drivers/char/hvc_console.h | 10 ++++++++++ include/asm-powerpc/xmon.h | 4 ++++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 95f24c9822b..6726da07c06 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 44160d5ebca..2f9759d625c 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 8c59818050e..42ffb17e15d 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 d83da3cbd08..5eb8e599e5c 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 */ -- GitLab From 1c21a2937b1f342a8f5d580203c3396557d53b6e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:19 +1000 Subject: [PATCH 0024/2509] [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 --- arch/powerpc/kernel/lparcfg.c | 6 +++--- arch/powerpc/kernel/machine_kexec_64.c | 4 ++-- arch/powerpc/kernel/msi.c | 2 +- arch/powerpc/kernel/rtas-proc.c | 14 +++++++------- arch/powerpc/kernel/rtas.c | 6 +++--- arch/powerpc/kernel/rtas_flash.c | 4 ++-- arch/powerpc/kernel/rtas_pci.c | 4 ++-- arch/powerpc/kernel/smp.c | 4 ---- arch/powerpc/kernel/time.c | 10 +++++----- arch/powerpc/platforms/maple/time.c | 2 -- include/asm-powerpc/smp.h | 2 ++ include/asm-powerpc/time.h | 1 + 12 files changed, 28 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 1e656b43ad7..827a5726a03 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 704375bda73..631dfd614b2 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 c62d1012c01..3bb7d3dd28b 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 f9c6abc84a9..1be9fe38bcb 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 34843c31841..2a60bd3e3af 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 0a5e22b2272..09ded5c424a 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 3ab88a9dc70..589a2797eac 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 1457aa0a08f..ba7989ffaee 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 73401e83739..c73fc33aa81 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 9f7579b38c7..53bca132fb4 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 505f35bacaa..1cd43e3d94f 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 ce5de6e0e69..febd581ec9b 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); -- GitLab From 3ff1999b2c84e1486e80fbd3ca12b1663dc3408b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:21 +1000 Subject: [PATCH 0025/2509] [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 --- arch/powerpc/platforms/pseries/firmware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 9d3a40f4597..5a707da3f5c 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; -- GitLab From 541b2755c2ef7dd2242ac606c115daa11e43ef69 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:23 +1000 Subject: [PATCH 0026/2509] [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 --- arch/powerpc/platforms/pseries/iommu.c | 15 +++++++++------ arch/powerpc/platforms/pseries/lpar.c | 2 +- arch/powerpc/platforms/pseries/ras.c | 2 +- arch/powerpc/platforms/pseries/rtasd.c | 4 ++-- arch/powerpc/platforms/pseries/setup.c | 4 ++-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 176f1f39d2d..9a12908510f 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 2cbaedb17f3..3b4651b6ee0 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 2b548afd100..d20b96e22c2 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 7d3e2b0bd4d..c9ffd8c225f 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 f5d29f5b13c..90beb444e1d 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"); -- GitLab From a560643e21e1ac10f7398b45111aecdd7f47a4a5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 May 2008 14:30:48 +1000 Subject: [PATCH 0027/2509] [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 --- arch/powerpc/kernel/entry_32.S | 8 ++++++++ include/asm-powerpc/thread_info.h | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 3a05e9f93d4..888a364043a 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 e079e81051f..b705c2a7651 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__ -- GitLab From 0b2cca804ee40495bc92449c3e22f3c3a3f2977a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 29 Apr 2008 01:38:13 +1000 Subject: [PATCH 0028/2509] [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 --- arch/powerpc/sysdev/6xx-suspend.S | 52 +++++++++++++++++++++++++++++++ arch/powerpc/sysdev/Makefile | 4 +++ include/asm-powerpc/mpc6xx.h | 6 ++++ 3 files changed, 62 insertions(+) create mode 100644 arch/powerpc/sysdev/6xx-suspend.S create mode 100644 include/asm-powerpc/mpc6xx.h diff --git a/arch/powerpc/sysdev/6xx-suspend.S b/arch/powerpc/sysdev/6xx-suspend.S new file mode 100644 index 00000000000..21cda085d92 --- /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 6d386d0071a..2cc50520a69 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 00000000000..effc2291beb --- /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 -- GitLab From 7bc228b1ef71f395aeb89bdf81bf95556b08b374 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 15 May 2008 05:16:44 +1000 Subject: [PATCH 0029/2509] [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 --- include/asm-powerpc/ioctl.h | 58 +------------------------------------ 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h index 8eb99848c40..57d68304218 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 */ -- GitLab From 09e67ca2c523544e6b38aa570a5f62a0cf20b87b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 16 May 2008 11:57:45 +1000 Subject: [PATCH 0030/2509] [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 --- arch/powerpc/kernel/of_device.c | 48 --------------------------------- drivers/of/device.c | 48 +++++++++++++++++++++++++++++++++ include/asm-powerpc/of_device.h | 2 -- include/linux/of_device.h | 3 +++ 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 5748ddb47d9..e9be908f199 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 6526e139a46..3c123990ca2 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 afe338217d9..d3a74e00a3e 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 */ -- GitLab From 493d35863dbb692c38c1415fd83d88dfb902ae37 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 14 May 2008 16:22:58 -0700 Subject: [PATCH 0031/2509] 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 --- kernel/mutex-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c index 3aaa06c561d..1d94160eb53 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()); } -- GitLab From 75bd2ef1457998791cfc89cd59927574488fc22a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:09:23 -0600 Subject: [PATCH 0032/2509] bsg: cdev lock_kernel() pushdown Push the cdev lock_kernel call into bsg_open(). Signed-off-by: Jonathan Corbet --- block/bsg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/bsg.c b/block/bsg.c index f0b7cd34321..dbe3ffd505c 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); -- GitLab From 0c401df37ef9f45f35390a5574e24cbf3f916acf Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:18 -0600 Subject: [PATCH 0033/2509] cris: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into cris drivers. Signed-off-by: Jonathan Corbet --- arch/cris/arch-v10/drivers/gpio.c | 3 ++ arch/cris/arch-v10/drivers/sync_serial.c | 34 ++++++++++++++--------- arch/cris/arch-v32/drivers/mach-a3/gpio.c | 4 +++ arch/cris/arch-v32/drivers/mach-fs/gpio.c | 5 +++- arch/cris/arch-v32/drivers/sync_serial.c | 33 +++++++++++++--------- 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 68a998bd106..86048e697eb 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 069546e342c..91fea623c7c 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 de107dad9f4..ef98608e506 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 7863fd4efc2..fe1fde89388 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 47c377df6fb..d2a0fbf5341 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) -- GitLab From 7558da942e51933b5e6aa5e851d4da1df0cd6752 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:50 -0600 Subject: [PATCH 0034/2509] mips: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into MIPS-specific drivers. Signed-off-by: Jonathan Corbet --- arch/mips/kernel/rtlx.c | 7 ++++++- arch/mips/kernel/vpe.c | 12 +++++++++--- arch/mips/sibyte/common/sb_tbprof.c | 25 ++++++++++++++++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index b88f1c18ff4..b5564196123 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 2794501ff30..972b2d2b840 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 63b444eaf01..28b012ab8dc 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) -- GitLab From 1fa984b583a809423ddb1d88fa46484071f85f80 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:11:26 -0600 Subject: [PATCH 0035/2509] sh: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the sh gio driver. Signed-off-by: Jonathan Corbet --- arch/sh/boards/landisk/gio.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c index 17025080db3..0c15b0a50b9 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) -- GitLab From 5119e92efc733d730b34f9605a5ae61fdc4bf649 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:12:01 -0600 Subject: [PATCH 0036/2509] x86: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the x86 msr and cpuid drivers. Signed-off-by: Jonathan Corbet --- arch/x86/kernel/cpuid.c | 25 +++++++++++++++++-------- arch/x86/kernel/msr.c | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index daff52a6224..71f1c2654be 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 1f3abe048e9..a153b3905f6 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; } -- GitLab From 3db633ee352bfe20d4a2b0c3c8a46ce31a6c7149 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:02 -0600 Subject: [PATCH 0037/2509] i2c: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/i2c/i2c-dev.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c81c2..006a5857256 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) -- GitLab From 0911810755fc9f15659cc3cb43912633b90027a0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:33 -0600 Subject: [PATCH 0038/2509] cosa: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/net/wan/cosa.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index b0fce1387ea..5827324e9d9 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) -- GitLab From 0bec0bba7a507bdaf07312fcabdc00b5576abb32 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:25:03 -0600 Subject: [PATCH 0039/2509] pcmcia: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/pcmcia/pcmcia_ioctl.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 5f186abca10..138396ef5be 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 */ /*====================================================================*/ -- GitLab From 8b09dee67f484e9b42114b1a1f068e080fd7aa56 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0040/2509] 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 --- include/linux/rcupdate.h | 2 -- kernel/rcupreempt.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index d42dbec0608..ec2fc5b3264 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 e1cdf196a51..5e02b774070 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; -- GitLab From 4446a36ff8c74ac3b32feb009b651048e129c6af Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0041/2509] 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 --- include/linux/rcuclassic.h | 3 + include/linux/rcupdate.h | 22 ++ include/linux/rcupreempt.h | 42 +++- init/main.c | 1 + kernel/rcupdate.c | 20 +- kernel/rcupreempt.c | 414 +++++++++++++++++++++++++++++++++---- 6 files changed, 434 insertions(+), 68 deletions(-) diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index b3aa05baab8..8c774905dcf 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 ec2fc5b3264..411969cb524 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 8a05c7e20bc..f04b64eca63 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 f7fb20021d4..a9cc3e0803d 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 c09605f8d16..a4e329d9288 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 5e02b774070..aaa7976bd85 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 -- GitLab From 8db559b83009bed92e1b5dd13a651ff273d9ff62 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0042/2509] 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 --- kernel/rcuclassic.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index f4ffbd0f306..d8348792f9f 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(); } -- GitLab From 70f12f848d3e981479b4f6f751e73c14f7c13e5b Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0043/2509] 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 --- include/linux/rcupdate.h | 2 ++ kernel/rcupdate.c | 55 +++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 411969cb524..e8b4039cfb2 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 a4e329d9288..4a74b8d48d9 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(); -- GitLab From 2326974df29988181b6b69ed6fbf42b17adf916f Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0044/2509] 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 --- kernel/rcutorture.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 33acc424667..0334b6a8bac 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++) { -- GitLab From 32300751b4079cb5688453baa94711579d4285d5 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0045/2509] 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 --- Documentation/RCU/NMI-RCU.txt | 3 + Documentation/RCU/RTFP.txt | 108 ++++++++++++++++++++++++++++++++ Documentation/RCU/checklist.txt | 89 +++++++++++++++++--------- Documentation/RCU/whatisRCU.txt | 58 +++++++++++------ 4 files changed, 210 insertions(+), 48 deletions(-) diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt index c64158ecde4..a6d32e65d22 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 39ad8f56783..9f711d2df91 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 42b01bc2e1b..cf5562cbe35 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 e0d6d99b8f9..e04d643a9f5 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. -- GitLab From 82524746c27fa418c250a56dd7606b9d3fc79826 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 12 May 2008 21:21:05 +0200 Subject: [PATCH 0046/2509] 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 --- arch/ia64/sn/kernel/irq.c | 1 + crypto/async_tx/async_tx.c | 1 + drivers/infiniband/hw/ipath/ipath_verbs.c | 1 + .../infiniband/hw/ipath/ipath_verbs_mcast.c | 3 +- drivers/net/macvlan.c | 2 +- include/linux/dcache.h | 1 + include/linux/list.h | 367 ---------------- include/linux/rculist.h | 396 ++++++++++++++++++ kernel/pid.c | 1 + lib/textsearch.c | 1 + net/802/psnap.c | 1 + net/8021q/vlan.c | 1 + net/bridge/br_fdb.c | 1 + net/bridge/br_stp.c | 1 + net/netlabel/netlabel_domainhash.c | 3 +- 15 files changed, 409 insertions(+), 372 deletions(-) create mode 100644 include/linux/rculist.h diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 53351c3cd7b..96c31b4180c 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 c6e772fc5cc..095c798d317 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 e0ec540042b..5d830d87ebc 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 9e5abf9c309..d73e3223287 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 c36a03ae9bf..860d75d81f8 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 2a6639407c8..1f5cebf10a2 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 08cf4f65188..139ec41d9c2 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -84,65 +84,6 @@ static inline void list_add_tail(struct list_head *new, struct list_head *head) __list_add(new, head->prev, 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. @@ -173,36 +114,6 @@ static inline void list_del(struct list_head *entry) 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 @@ -226,25 +137,6 @@ static inline void list_replace_init(struct list_head *old, INIT_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. @@ -368,62 +260,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. @@ -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 00000000000..aa9b3eb1568 --- /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 20d59fa2d49..30bd5d4b2ac 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 be8bda3862f..a3e500ad51d 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 31128cb92a2..ea464393144 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 2a739adaa92..e7ddbfa0e02 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 72c5976a5ce..142060f0205 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 e38034aa56f..9e96ffcd29a 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 02c2f7c0b25..643c032a3a5 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -30,8 +30,7 @@ */ #include -#include -#include +#include #include #include #include -- GitLab From 10aa9d2cf9878757b003023d33ff90a37aa3044b Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 12 May 2008 21:21:06 +0200 Subject: [PATCH 0047/2509] 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 --- include/linux/rculist.h | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/include/linux/rculist.h b/include/linux/rculist.h index aa9b3eb1568..8d2c81fccfe 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; } -- GitLab From d7c0651390b6a03ad53f99faec0ba88109d7191d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:06 +0200 Subject: [PATCH 0048/2509] 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 --- kernel/rcupreempt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index aaa7976bd85..27d0748d8d3 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. */ -- GitLab From 78b0e0e9b27b62c4b22f05a147f7a80fa58b1ae3 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:06 +0200 Subject: [PATCH 0049/2509] 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 --- include/linux/rculist.h | 48 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 8d2c81fccfe..b0f39be08b6 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 -- GitLab From e19a98967f49cb63352b3db4818983ea2cec24ba Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 14 May 2008 16:23:00 -0700 Subject: [PATCH 0050/2509] 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 --- kernel/rcupreempt_trace.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/rcupreempt_trace.c b/kernel/rcupreempt_trace.c index 49ac4947af2..5edf82c34bb 100644 --- a/kernel/rcupreempt_trace.c +++ b/kernel/rcupreempt_trace.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include -- GitLab From 247ab1a80595100bd7ea61d174f8b7b7e5f8d4bb Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 14 May 2008 16:23:00 -0700 Subject: [PATCH 0051/2509] 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 --- kernel/rcupreempt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 27d0748d8d3..b8e4cdae4e8 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include -- GitLab From 711bbdd659b685b45d3f28b29a00f17be6484f38 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 17 May 2008 08:26:25 +0200 Subject: [PATCH 0052/2509] 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 --- net/netfilter/nf_conntrack_netlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 0edefcfc594..077bcd22879 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 -- GitLab From 4f9c16ccfa26691dbb9a5d9e7d5098eb934ccdbe Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 30 Apr 2008 16:20:19 +0200 Subject: [PATCH 0053/2509] [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 --- sound/soc/codecs/tlv320aic3x.c | 225 +++++++++++++-------------------- sound/soc/codecs/tlv320aic3x.h | 4 + 2 files changed, 95 insertions(+), 134 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 09b1661b8a3..738b3b634d7 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 d0cdeeb629d..d49d001e6e4 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 -- GitLab From 54e7e6167d29a4a98207884b2fbd28b0b3fe91f6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 30 Apr 2008 16:20:52 +0200 Subject: [PATCH 0054/2509] [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 --- sound/soc/codecs/tlv320aic3x.c | 53 ++++++++++++++++++++++++++++++++++ sound/soc/codecs/tlv320aic3x.h | 49 ++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 738b3b634d7..957996e0eba 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 d49d001e6e4..c1dd1ac0cea 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; -- GitLab From eeec12bf7b7d80d1c9cae5aae0dff7e2f928c64b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 30 Apr 2008 19:27:40 +0200 Subject: [PATCH 0055/2509] [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 --- include/sound/soc-dapm.h | 2 ++ sound/soc/soc-dapm.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index a105b01e06d..40cc695b69b 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 af3326c6350..9fd5ee818e8 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1342,6 +1342,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 -- GitLab From 650f6b13318bce6a8d59bfa48fe15b5832623cbc Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 1 May 2008 10:49:18 +0200 Subject: [PATCH 0056/2509] [ALSA] sound: fix export symbol typo Signed-off-by: Stephen Rothwell Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9fd5ee818e8..c60200ccde6 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 -- GitLab From 1894c59fdb63692f5ba2576875cc558b856935ca Mon Sep 17 00:00:00 2001 From: Tim Niemeyer Date: Mon, 5 May 2008 14:16:12 +0200 Subject: [PATCH 0057/2509] [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 --- sound/soc/s3c24xx/neo1973_wm8753.c | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 0e9d1c5f248..e469186a407 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); } -- GitLab From 87af38dafe4f930921b9217c21ec6d72cad56bcc Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 7 May 2008 12:05:10 +0200 Subject: [PATCH 0058/2509] [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 --- sound/drivers/Kconfig | 1 + sound/pci/ac97/ac97_patch.c | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 602b58e3b55..159137bf4c1 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 1292dcee072..92817f7d46d 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; } -- GitLab From 48008b598bb9cfffbd871512f49d84eb5b885a00 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 8 May 2008 13:01:32 +0200 Subject: [PATCH 0059/2509] [ALSA] i2c: cs8427.c use put_unaligned helper Signed-off-by: Harvey Harrison Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/i2c/cs8427.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index e57e9cbe6a0..9c3d361accf 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; -- GitLab From f3e9d5d1fd6a164611043c053de585a35d76d6a9 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 8 May 2008 15:42:15 +0200 Subject: [PATCH 0060/2509] [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 --- sound/usb/caiaq/caiaq-audio.c | 1 + sound/usb/caiaq/caiaq-device.c | 12 +++++++++--- sound/usb/caiaq/caiaq-device.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c index 24970a5c888..b3a60332583 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 a972f77bd78..83175083e50 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 96a491379c6..f9fbdbae269 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 -- GitLab From c17cf06bfc4417a79d452c266e819c510f6a8344 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 May 2008 12:45:56 +0200 Subject: [PATCH 0061/2509] [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 --- sound/core/memalloc.c | 62 ------------------------------------------- 1 file changed, 62 deletions(-) diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 23b7bc02728..f5d6d8d1297 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -79,68 +79,6 @@ struct snd_mem_list { #define snd_assert(expr, args...) /**/ #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 -- GitLab From d023dc0aa25d6a4f7dd0d109179a2077d22a7ad2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:18:27 +0200 Subject: [PATCH 0062/2509] [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 --- sound/pci/oxygen/hifier.c | 2 +- sound/pci/oxygen/oxygen.c | 2 +- sound/pci/oxygen/oxygen_lib.c | 2 +- sound/pci/oxygen/virtuoso.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 090dd4354a2..c5d2c86cacb 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 63f185c1ed1..c1b30cc7593 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 897697d4350..6e3879527dc 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 7f84fa5deca..4618a622a29 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; -- GitLab From c13650079ba3bed1c0bdd9bf4a13274be7676ff6 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:19:53 +0200 Subject: [PATCH 0063/2509] [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 --- sound/pci/oxygen/oxygen.h | 2 ++ sound/pci/oxygen/oxygen_lib.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index a71c6e05926..6c6efede4d2 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 6e3879527dc..60bc1591734 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; -- GitLab From e58aee95806c9d2bbcfc84cb85ce958e360165ef Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:20:51 +0200 Subject: [PATCH 0064/2509] [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 --- sound/pci/oxygen/oxygen.c | 17 ++++++++++-- sound/pci/oxygen/oxygen.h | 6 ++++ sound/pci/oxygen/oxygen_io.c | 22 ++++++++++++--- sound/pci/oxygen/virtuoso.c | 54 +++++++++++++++++++----------------- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index c1b30cc7593..8287ac28fe7 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 6c6efede4d2..29c9fa4964b 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 5569606ee87..83f135f80df 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 4618a622a29..110786b2e3b 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) -- GitLab From bbbfb5526650cb9d01c5c230a4e3cbbc18474c41 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:21:48 +0200 Subject: [PATCH 0065/2509] [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 --- sound/pci/oxygen/hifier.c | 15 ++--- sound/pci/oxygen/oxygen.c | 27 ++++---- sound/pci/oxygen/virtuoso.c | 123 +++++++++++++++++------------------- 3 files changed, 77 insertions(+), 88 deletions(-) diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index c5d2c86cacb..0e425d55450 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 8287ac28fe7..ad8d950fddc 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 110786b2e3b..bd9e2858351 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; -- GitLab From 75146fc0f9368ea41419792ac8bfdd19273b4473 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:22:43 +0200 Subject: [PATCH 0066/2509] [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 --- sound/pci/oxygen/hifier.c | 11 ++++++-- sound/pci/oxygen/oxygen.c | 26 +++++++++++++----- sound/pci/oxygen/virtuoso.c | 54 +++++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 0e425d55450..6e45a58ad14 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 ad8d950fddc..800ae304a24 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 bd9e2858351..e95dc5717ed 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); -- GitLab From 92215f3a178080bd9d7c65879499e9474e54d55c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:23:02 +0200 Subject: [PATCH 0067/2509] [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 --- sound/pci/oxygen/virtuoso.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index e95dc5717ed..abd5313d19b 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) -- GitLab From 4a4bc53bc52978dd6c918531921da925fd047d95 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:24:39 +0200 Subject: [PATCH 0068/2509] [ALSA] oxygen: add PM support Add suspend/resume support. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/oxygen/hifier.c | 5 ++ sound/pci/oxygen/oxygen.c | 12 ++++ sound/pci/oxygen/oxygen.h | 6 ++ sound/pci/oxygen/oxygen_lib.c | 100 ++++++++++++++++++++++++++++++++++ sound/pci/oxygen/oxygen_pcm.c | 1 + sound/pci/oxygen/virtuoso.c | 22 ++++++++ 6 files changed, 146 insertions(+) diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 6e45a58ad14..7442460583d 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 800ae304a24..7c8ae31eb46 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 29c9fa4964b..74a64488007 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 60bc1591734..22f37851045 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 b17c405e069..9680aa35f81 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 abd5313d19b..9a2c16bf94e 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) -- GitLab From d55d7a1cbbd069f8368ec5c67480d319e7b227b9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:25:39 +0200 Subject: [PATCH 0069/2509] [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 --- sound/pci/oxygen/oxygen_pcm.c | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 9680aa35f81..09a16e459de 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; } -- GitLab From ca1f30ad6c3f002d1d9b9355a53b8bbf2fe70588 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:26:01 +0200 Subject: [PATCH 0070/2509] [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 --- sound/pci/oxygen/oxygen_pcm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 09a16e459de..c4ad65a3406 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; -- GitLab From 4ba1327ab8ce179c40862f3dedb4ebaaa491d737 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:51:19 +0200 Subject: [PATCH 0071/2509] [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 --- include/sound/soc-dapm.h | 3 +++ sound/soc/soc-dapm.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 40cc695b69b..1f30616afe7 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 c60200ccde6..811d6527101 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1233,6 +1233,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 -- GitLab From 105f1c28442301237d20b05a3d52d9987614016f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:52:19 +0200 Subject: [PATCH 0072/2509] [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 --- include/sound/soc-dapm.h | 17 +++++++++- sound/soc/soc-dapm.c | 72 +++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 1f30616afe7..bf4cf0c1d37 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 811d6527101..1ef6d94b835 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,8 +944,63 @@ 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 -- GitLab From d0cc0d3a95cc3c022ee118072d243d3670ec1663 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:55:22 +0200 Subject: [PATCH 0073/2509] [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 --- sound/soc/codecs/tlv320aic3x.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 957996e0eba..cb8365ac0c0 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; -- GitLab From 25191c45aec54cd01b53391bb0b0e1e60377a5fc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:55:48 +0200 Subject: [PATCH 0074/2509] [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 --- sound/soc/pxa/corgi.c | 12 ++++-------- sound/soc/pxa/poodle.c | 14 +++++--------- sound/soc/pxa/spitz.c | 14 +++++--------- sound/soc/pxa/tosa.c | 14 ++++---------- 4 files changed, 18 insertions(+), 36 deletions(-) diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 7f32a116757..852f16d963a 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 7e830b21894..810f1fe158a 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 d8b8372db00..73a6df8709e 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 7346d7e5d06..fda2aa056d5 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; -- GitLab From 51e6a8411a9440f0fdba6cdd7d779e74f89debc4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:57:37 +0200 Subject: [PATCH 0075/2509] [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 --- sound/soc/at91/eti_b1_wm8731.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 1347dcf3f80..4a383a4a0ff 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); -- GitLab From 8f3112d7a847c2933a42ce29f17899f585d09106 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:03 +0200 Subject: [PATCH 0076/2509] [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 --- sound/soc/s3c24xx/neo1973_wm8753.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index e469186a407..79c5027273c 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; -- GitLab From acf497f996aa08f03c62a3150abd7939ae23de4c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:30 +0200 Subject: [PATCH 0077/2509] [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 --- sound/soc/davinci/davinci-evm.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index fcd16524033..4c70a0ed339 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); -- GitLab From 1a2505988ea650b61bd07722e99080a40ff27653 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:57 +0200 Subject: [PATCH 0078/2509] [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 --- sound/soc/omap/n810.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 6533563a601..c2afffbe8da 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); -- GitLab From f99a633a151686a599413bef758253dfd04887d1 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 15 May 2008 11:01:36 +0200 Subject: [PATCH 0079/2509] [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 --- sound/soc/omap/n810.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index c2afffbe8da..c32487b6c7b 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); } -- GitLab From 02330fbaaded5b603cba112e4bbf62cdadec159a Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 16 May 2008 12:18:29 +0200 Subject: [PATCH 0080/2509] [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 --- sound/pci/azt3328.c | 1192 +++++++++++++++++++++++++++++-------------- sound/pci/azt3328.h | 197 ++++++- 2 files changed, 968 insertions(+), 421 deletions(-) diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5f63af6b88a..b832333c302 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 679fa992e2b..3448fd626f8 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) -- GitLab From 9ad593f6d326e7a4664e3856520f6c042f82a37f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 16 May 2008 12:34:47 +0200 Subject: [PATCH 0081/2509] [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 --- sound/pci/hda/hda_intel.c | 124 ++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 18 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b3a618eb42c..6ba7ac01d9f 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); -- GitLab From b2efbbfba24efc8456d68d5af42d082ab1c2febc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:30:58 +0200 Subject: [PATCH 0082/2509] [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 --- sound/soc/codecs/ac97.c | 3 --- sound/soc/codecs/wm9712.c | 3 --- sound/soc/codecs/wm9713.c | 3 --- sound/soc/pxa/corgi.c | 4 ---- sound/soc/pxa/pxa2xx-i2s.c | 3 --- sound/soc/pxa/spitz.c | 3 --- sound/soc/pxa/tosa.c | 3 --- sound/soc/s3c24xx/neo1973_wm8753.c | 4 ---- sound/soc/s3c24xx/s3c2443-ac97.c | 3 --- sound/soc/s3c24xx/s3c24xx-i2s.c | 5 ----- sound/soc/s3c24xx/s3c24xx-pcm.c | 4 ---- sound/soc/s3c24xx/smdk2443_wm9710.c | 3 --- sound/soc/soc-core.c | 4 ---- sound/soc/soc-dapm.c | 5 ----- 14 files changed, 50 deletions(-) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 2a1ffe39690..7bf2081b46f 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 76c1e2d33e7..89efe40c7c3 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 1f241161445..9e6b2fd7262 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 852f16d963a..edeea63e80e 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 42507103097..35090c2870f 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 73a6df8709e..092b5c776b4 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 fda2aa056d5..465ff0f458e 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 79c5027273c..c1a0161bc72 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 e81d9a6c83d..0eed140dcd9 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 1ed6afd4545..ddf87246c77 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 7806ae61461..ef599745159 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 b4a56302b9a..8515d6ff03f 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 e148db940cf..0318d8abe3e 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 1ef6d94b835..8a3192bcee7 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 -- GitLab From 1ef6ab75c7deef931d6308af282ed7d8e480e77f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:31:55 +0200 Subject: [PATCH 0083/2509] [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 --- include/sound/soc.h | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index d3c8c033dff..73accbcfbd2 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; -- GitLab From 1a189b97190d3f0f8cf0379a799d3555b2d648bb Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 13 Apr 2008 21:41:55 +0100 Subject: [PATCH 0084/2509] [ARM] pxa: Add bare bones PWM API Signed-off-by: Russell King --- arch/arm/Kconfig | 3 +++ include/linux/pwm.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 include/linux/pwm.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..c274dbb89a8 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 00000000000..3945f803d51 --- /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 */ -- GitLab From 75540c1ac3c7bd72ac8e092058f9714875239995 Mon Sep 17 00:00:00 2001 From: eric miao Date: Sun, 13 Apr 2008 21:44:04 +0100 Subject: [PATCH 0085/2509] [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 --- arch/arm/mach-pxa/Kconfig | 5 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/devices.c | 60 ++++++++ arch/arm/mach-pxa/devices.h | 5 + arch/arm/mach-pxa/pwm.c | 299 ++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/pxa25x.c | 6 +- arch/arm/mach-pxa/pxa27x.c | 5 +- arch/arm/mach-pxa/pxa3xx.c | 4 + 8 files changed, 382 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-pxa/pwm.c diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a682049..9c01505b182 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 0e6d05bb81a..02cbc3cfbe0 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 d6c05b6eab3..794a1076db7 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 fcab017f27e..e620a3373d4 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 00000000000..70fb3ca6a05 --- /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 e5b417d14bb..2bed3f98d41 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 7e945836e12..bc2e80f6967 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 644550bfa33..0f717df1fdb 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[] = { -- GitLab From 02a8e76979f9b439642e67955edb865c112926f6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:15:32 +0100 Subject: [PATCH 0086/2509] [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 --- arch/arm/common/sharpsl_pm.c | 2 ++ arch/arm/mach-pxa/corgi_pm.c | 2 ++ arch/arm/mach-pxa/spitz_pm.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 5bba5255b11..5736c987c80 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 0a85f706e88..ae91c4b1135 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 23f050feb20..48396f4eb26 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, -- GitLab From 284d115ec9b70d7c38752d10ad393a198db07a4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:32:16 +0100 Subject: [PATCH 0087/2509] [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 --- arch/arm/mach-pxa/em-x270.c | 1 + arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- drivers/usb/gadget/pxa2xx_udc.c | 10 +- include/asm-arm/arch-pxa/pxa-regs.h | 412 -------------------------- include/asm-arm/arch-pxa/pxa25x-udc.h | 163 ++++++++++ include/asm-arm/arch-pxa/pxa27x-udc.h | 256 ++++++++++++++++ 7 files changed, 430 insertions(+), 416 deletions(-) create mode 100644 include/asm-arm/arch-pxa/pxa25x-udc.h create mode 100644 include/asm-arm/arch-pxa/pxa27x-udc.h diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index edc4f07a230..1269ac99150 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 7e945836e12..cdaf573e0f1 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 644550bfa33..7fbe78649da 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 08f699b1fc5..63db96adc0b 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 4b2ea1e95c5..68d74287730 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -599,418 +599,6 @@ #define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ -/* - * 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 00000000000..840305916b6 --- /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 00000000000..9cf0b1f8811 --- /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 -- GitLab From 0be9898adb6f58fee44f0fec0bbc0eac997ea9eb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:31:28 +0200 Subject: [PATCH 0088/2509] [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 --- include/sound/soc-dapm.h | 3 ++- include/sound/soc.h | 28 ++++++++++++++++++---- sound/soc/codecs/tlv320aic3x.c | 26 ++++++++++---------- sound/soc/codecs/wm8731.c | 28 +++++++++++----------- sound/soc/codecs/wm8750.c | 36 ++++++++++++++-------------- sound/soc/codecs/wm8753.c | 36 ++++++++++++++-------------- sound/soc/codecs/wm9712.c | 28 +++++++++++----------- sound/soc/codecs/wm9713.c | 26 ++++++++++---------- sound/soc/soc-core.c | 25 +++++++++---------- sound/soc/soc-dapm.c | 44 ++++++++++++++++------------------ 10 files changed, 150 insertions(+), 130 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index bf4cf0c1d37..f8223fae580 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 73accbcfbd2..bca9538d9e5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -102,6 +102,24 @@ .get = xhandler_get, .put = xhandler_put, \ .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 */ @@ -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 cb8365ac0c0..dc8a38d9e53 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 0cf9265fca8..0f28aa4bccc 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 16cd5d4d5ad..62423f4493b 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 fb41826c4c4..9032b0c07c8 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 89efe40c7c3..e26cfcf0b4f 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 9e6b2fd7262..4863636e9d5 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 0318d8abe3e..a05b3450aee 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 8a3192bcee7..728f3ac2f30 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 -- GitLab From 3ff3f64ba04b3e5a86dce5239b10268798f68ad7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:32:25 +0200 Subject: [PATCH 0089/2509] [ALSA] ASoC: core checkpatch cleanups Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-core.c | 100 +++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a05b3450aee..a3f091e0843 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); -- GitLab From a65f0568f6cc8433877fb71dd7d36b551854b0bc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:54:43 +0200 Subject: [PATCH 0090/2509] [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 --- sound/soc/codecs/wm8731.c | 16 ++++------------ sound/soc/codecs/wm8750.c | 16 ++++------------ sound/soc/codecs/wm8753.c | 17 ++++------------- sound/soc/codecs/wm9712.c | 15 ++++----------- sound/soc/codecs/wm9713.c | 15 ++++----------- 5 files changed, 20 insertions(+), 59 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0f28aa4bccc..5acf43ab104 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 62423f4493b..1f11ad24551 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 9032b0c07c8..c32e6326be6 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 e26cfcf0b4f..d9789f1c890 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 4863636e9d5..4f516a5a561 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; -- GitLab From 33e5b22285f63ede858c00456f3ffbc2ea79d6cf Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 14 Apr 2008 14:26:44 +0200 Subject: [PATCH 0091/2509] [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 --- sound/soc/s3c24xx/s3c24xx-i2s.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index ddf87246c77..4c52f7946d9 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; -- GitLab From aea3bfbcfb0453217c8da6cfdc1b2394d214bee5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 20 May 2008 14:22:44 +0200 Subject: [PATCH 0092/2509] [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 --- sound/pci/Kconfig | 2 +- sound/pci/ice1712/envy24ht.h | 10 +- sound/pci/ice1712/ice1712.h | 2 + sound/pci/ice1712/ice1724.c | 213 +++++++++++++++++++++++++++-------- 4 files changed, 177 insertions(+), 50 deletions(-) diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 7e474210957..d95fbb2b5b9 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 43b9e3e858b..a0c5e009bb4 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 3208901c740..762fbd7a750 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 67350901772..e596d777d9d 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)); } } -- GitLab From 6536d2891ba2c4e837ba8478dc13bb173ed24a23 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 21 May 2008 10:45:16 -0500 Subject: [PATCH 0093/2509] 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 --- fs/jfs/super.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 50ea6545173..0288e6d7936 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); -- GitLab From 2ba4cc319ab26c56205d4f23724c4748a553c845 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 13 May 2008 15:37:05 +0200 Subject: [PATCH 0094/2509] rcu: fix nf_conntrack_helper.c build bug Signed-off-by: Ingo Molnar --- net/netfilter/nf_conntrack_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 7d1b1170374..8e0b4c8f62a 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 -- GitLab From f70c5253b41444fd2779e1f76bfe25811d9b8c23 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:22:36 +0100 Subject: [PATCH 0095/2509] [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 --- drivers/rtc/rtc-at91rm9200.c | 2 -- drivers/rtc/rtc-at91sam9.c | 1 - drivers/rtc/rtc-omap.c | 1 - drivers/rtc/rtc-s3c.c | 2 -- 4 files changed, 6 deletions(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 39e64ab1ecb..2af1e6fb71c 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 38d8742a4bd..f0246ef413a 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 58f81c77494..eb23d8423f4 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 f26e0cad8f1..2c6e4671e38 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 -- GitLab From 2dba8518b7761aee3ba757b298efa15dd34eff18 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:08:04 +0100 Subject: [PATCH 0096/2509] [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 --- drivers/rtc/rtc-pl031.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 2fd49edcc71..08b4610ec5a 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; } -- GitLab From a190901c6b5f1f4a31681e8c69d811a4f9426e2b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:08:36 +0100 Subject: [PATCH 0097/2509] [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 --- arch/arm/mach-integrator/Makefile | 2 +- arch/arm/mach-integrator/time.c | 223 ------------------------------ drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-pl030.c | 217 +++++++++++++++++++++++++++++ 5 files changed, 229 insertions(+), 224 deletions(-) delete mode 100644 arch/arm/mach-integrator/time.c create mode 100644 drivers/rtc/rtc-pl030.c diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 158daaf9e3b..6a5ef8d30b1 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 8508a0db3ea..00000000000 --- 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 6cc2c033023..1b26eeb52c9 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 872f1218ff9..af3ee6652ce 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 00000000000..8448eeb9d67 --- /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"); -- GitLab From 7da285b626860eb6d35e08ae33eba90f0e83ad58 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:26:48 +0100 Subject: [PATCH 0098/2509] [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 --- drivers/rtc/rtc-at91rm9200.c | 2 -- drivers/rtc/rtc-s3c.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 2af1e6fb71c..9c3db934cc2 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 2c6e4671e38..fed86e507fd 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 -- GitLab From 797276ec9e4d2ee210e11068a2ce815394fe8c58 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:30:41 +0100 Subject: [PATCH 0099/2509] [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 --- drivers/rtc/rtc-sa1100.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 82f62d25f92..e31a687b44b 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; -- GitLab From bedd78ca786c1d18c2a2785c7e40593dc9c9870f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:31:29 +0100 Subject: [PATCH 0100/2509] [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 --- arch/arm/common/Makefile | 1 - arch/arm/common/rtctime.c | 434 -------------------------------------- include/asm-arm/rtc.h | 43 ---- 3 files changed, 478 deletions(-) delete mode 100644 arch/arm/common/rtctime.c delete mode 100644 include/asm-arm/rtc.h diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 3d0b9fa42f8..325e4b6a6af 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 aa8f7739c82..00000000000 --- 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 1a5c9232a91..00000000000 --- 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 -- GitLab From 21451155d8858773ee764e9218de2ca0f4d6fc38 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Apr 2008 00:05:24 +1000 Subject: [PATCH 0101/2509] [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 --- drivers/of/gpio.c | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 000681e98f2..1c9cab844f1 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; -- GitLab From 2ca7633dc73405ee775a2e9b7961b47a38bc882d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 11 May 2008 10:40:47 +1000 Subject: [PATCH 0102/2509] [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 --- arch/powerpc/kernel/vdso64/vdso64.lds.S | 6 +++--- include/asm-powerpc/ppc_asm.h | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 932b3fdb34b..7d6585f9027 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 2dbd4e7884f..ef96bfd4ef4 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 -- GitLab From 475ca391b490a683d66bf19999a8a7a24913f139 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 22 May 2008 06:59:23 +1000 Subject: [PATCH 0103/2509] [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 --- arch/powerpc/sysdev/mpic.c | 9 ++++++--- include/asm-powerpc/mpic.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 8619f2a3f1f..466e2183e86 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 943c5a3fac8..6802570f424 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 -- GitLab From 72cac213fda6a2dd402e91692b70e175795eab7d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 May 2008 14:21:30 +1000 Subject: [PATCH 0104/2509] [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 --- arch/powerpc/platforms/cell/axon_msi.c | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index c39f5c225f2..8b055bce27f 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 */ -- GitLab From 80d267f9aee6f1b5df602b5a19fb7b4923f17db2 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 May 2008 14:22:21 +1000 Subject: [PATCH 0105/2509] [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 --- arch/powerpc/kernel/kprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index c176c513566..23545a2f51f 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 -- GitLab From bd3bff9e20f454b242d979ec2f9a4dca0d5fa06f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0106/2509] 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 --- include/linux/sched.h | 26 ++++++++++++++++++++++++++ kernel/sched.c | 3 +++ 2 files changed, 29 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 5395a6176f4..717cab8a0c8 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 cfa222a9153..463dcdb36ef 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; /* -- GitLab From 7c731e0a495e25e79dc1e9e68772a67a55721a65 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0107/2509] 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 --- include/linux/sched.h | 2 ++ kernel/sched.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 717cab8a0c8..6e26f1fdbfe 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 463dcdb36ef..73e60085236 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) { -- GitLab From 502825282e6f79c975a644afc124432ec1744de4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0108/2509] 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 --- include/linux/preempt.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 23f0c54175c..36b03d50bf4 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 -- GitLab From ffdc1a09ae7e2cbd714a446ee38a27f625b5f1c8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0109/2509] 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 --- include/linux/linkage.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 2119610b24f..14f329c64ba 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 -- GitLab From 23adec554a7648f99c8acc0caf49c66320cd2b84 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0110/2509] 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 --- arch/x86/kernel/vsyscall_64.c | 3 ++- arch/x86/vdso/vclock_gettime.c | 15 ++++++++------- arch/x86/vdso/vgetcpu.c | 3 ++- include/asm-x86/vsyscall.h | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 61efa2f7d56..4063dfa2a02 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 23476c2ebfc..5cb8f754c52 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 c8097f17f8a..9fbc6b20026 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 17b3700949b..6b66ff905af 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 -- GitLab From 6e766410c4babd37bc7cd5e25009c179781742c8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 May 2008 21:20:41 +0200 Subject: [PATCH 0111/2509] 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 --- lib/smp_processor_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 6c90fb90e19..e555ab62fba 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(); -- GitLab From 16444a8a40d4c7b4f6de34af0cae1f76a4f6c901 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0112/2509] 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 --- Makefile | 4 ++ arch/x86/Kconfig | 1 + arch/x86/kernel/entry_32.S | 27 ++++++++ arch/x86/kernel/entry_64.S | 37 ++++++++++ include/linux/ftrace.h | 38 ++++++++++ kernel/Makefile | 1 + kernel/trace/Kconfig | 5 ++ kernel/trace/Makefile | 3 + kernel/trace/ftrace.c | 138 +++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 2 + 10 files changed, 256 insertions(+) create mode 100644 include/linux/ftrace.h create mode 100644 kernel/trace/Kconfig create mode 100644 kernel/trace/Makefile create mode 100644 kernel/trace/ftrace.c diff --git a/Makefile b/Makefile index 20b32351906..b4a273f19b5 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 fe361ae7ef2..c742dfeb0db 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 2a609dc3271..f47b9b5440d 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 556a8df522a..f046e0c6488 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 00000000000..b96ef14c249 --- /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 1c9938addb9..fa05f6d8bdb 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 00000000000..8185c91417b --- /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 00000000000..bf4fd215a6a --- /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 00000000000..b6a80b98a3f --- /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 d2099f41aa1..d8b6279a9b4 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 -- GitLab From bc0c38d139ec7fcd5c030aea16b008f3732e42ac Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0113/2509] 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 --- kernel/Makefile | 1 + kernel/trace/Kconfig | 5 + kernel/trace/Makefile | 2 + kernel/trace/trace.c | 1547 +++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 184 +++++ 5 files changed, 1739 insertions(+) create mode 100644 kernel/trace/trace.c create mode 100644 kernel/trace/trace.h diff --git a/kernel/Makefile b/kernel/Makefile index fa05f6d8bdb..7e344e7b0cb 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 8185c91417b..ce70677afbf 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 bf4fd215a6a..7af40317525 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 00000000000..1b8eca7650d --- /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 00000000000..3173a93561d --- /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 */ -- GitLab From 1b29b01887e6032dcaf818c14999c7a39593b4e7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0114/2509] 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 --- kernel/trace/Kconfig | 13 ++++++ kernel/trace/Makefile | 1 + kernel/trace/trace_functions.c | 73 ++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 kernel/trace/trace_functions.c diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index ce70677afbf..1399f372b5d 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 7af40317525..6bb5e50b4a4 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 00000000000..82988c5336e --- /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); -- GitLab From 35e8e302e5d6e32675df2fc1dd3a53dfa6630dc1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0115/2509] 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 --- kernel/trace/Kconfig | 11 +++ kernel/trace/Makefile | 1 + kernel/trace/trace_sched_switch.c | 116 ++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 kernel/trace/trace_sched_switch.c diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 1399f372b5d..5d6aa92866c 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 6bb5e50b4a4..6b54ceb7f16 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 00000000000..3e4771d3b89 --- /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); -- GitLab From 352ad25aa4a189c667cb2af333948d34692a2d27 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0116/2509] 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 --- include/linux/ftrace.h | 23 ++- kernel/trace/Kconfig | 13 ++ kernel/trace/Makefile | 1 + kernel/trace/trace_sched_wakeup.c | 310 ++++++++++++++++++++++++++++++ 4 files changed, 343 insertions(+), 4 deletions(-) create mode 100644 kernel/trace/trace_sched_wakeup.c diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b96ef14c249..db8a5e7abe4 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 5d6aa92866c..892ecc94a82 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 6b54ceb7f16..5508cdb19ae 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 00000000000..7c3ccefcf4c --- /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); -- GitLab From 81d68a96a39844853b37f20cc8282d9b65b78ef3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0117/2509] 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 --- arch/x86/kernel/process_64.c | 3 + arch/x86/lib/Makefile | 1 + arch/x86/lib/thunk_32.S | 47 ++++ arch/x86/lib/thunk_64.S | 19 +- include/asm-x86/irqflags.h | 24 +-- include/linux/ftrace.h | 8 + include/linux/irqflags.h | 12 +- kernel/fork.c | 2 +- kernel/lockdep.c | 23 +- kernel/printk.c | 2 + kernel/trace/Kconfig | 18 ++ kernel/trace/Makefile | 1 + kernel/trace/trace_irqsoff.c | 402 +++++++++++++++++++++++++++++++++++ 13 files changed, 531 insertions(+), 31 deletions(-) create mode 100644 arch/x86/lib/thunk_32.S create mode 100644 kernel/trace/trace_irqsoff.c diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e2319f39988..dd349c92f05 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 76f60f52a88..84aa2883fe1 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 00000000000..650b11e00ec --- /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 e009251d4e9..bf9a7d5a542 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 c242527f970..24d71b1eb18 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 db8a5e7abe4..0a20445dcbc 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 e600c4e9b8c..5b711d4e9fd 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 19908b26cf8..d66d676dc36 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 81a4e4a3f08..e21924365ea 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 8fb01c32aa3..ae7d5b9e535 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 892ecc94a82..896df1cf6ad 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 5508cdb19ae..46be8647fb6 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 00000000000..a9131b0cf1a --- /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); -- GitLab From 6cd8a4bb2f97527a9ceb30bc77ea4e959c6a95e3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0118/2509] 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 --- arch/x86/kernel/process_32.c | 3 + include/linux/ftrace.h | 8 ++ include/linux/irqflags.h | 3 +- include/linux/preempt.h | 2 +- kernel/sched.c | 24 ++++- kernel/trace/Kconfig | 25 +++++ kernel/trace/Makefile | 1 + kernel/trace/trace_irqsoff.c | 184 +++++++++++++++++++++++++---------- 8 files changed, 197 insertions(+), 53 deletions(-) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f8476dfbb60..a30aa1f2607 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 0a20445dcbc..740c97dcf9c 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 5b711d4e9fd..2b1c2e58566 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 36b03d50bf4..72b1a10a59b 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 73e60085236..328494e28df 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 896df1cf6ad..6430016b98e 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 46be8647fb6..3fec653d653 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 a9131b0cf1a..8b1231633dc 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; } -- GitLab From 3d0833953e1b98b79ddf491dd49229eef9baeac1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: [PATCH 0119/2509] 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 --- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/ftrace.c | 237 ++++++++++++++++++++++++++ include/linux/ftrace.h | 18 ++ kernel/trace/Kconfig | 17 ++ kernel/trace/ftrace.c | 356 +++++++++++++++++++++++++++++++++++---- 5 files changed, 597 insertions(+), 32 deletions(-) create mode 100644 arch/x86/kernel/ftrace.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 5e618c3b472..e142091524b 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 00000000000..5dd58136ef0 --- /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 740c97dcf9c..90dbc0ee204 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; } -- GitLab From b0fc494fae96a7089f3651cb451f461c7291244c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0120/2509] 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 --- include/linux/ftrace.h | 6 ++ kernel/sysctl.c | 11 ++++ kernel/trace/ftrace.c | 125 +++++++++++++++++++++++++++++++++++------ 3 files changed, 124 insertions(+), 18 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 90dbc0ee204..ccd8537dbdb 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 29116652dca..efaf7c5500e 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 d1ae2ba2527..d3de37299ba 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; } -- GitLab From dfa60aba04dae7833d75b2e2be124bb7cfb8239f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0121/2509] 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 --- arch/x86/kernel/alternative.c | 4 ++-- arch/x86/kernel/ftrace.c | 40 +++++++++++++++++++++-------------- include/asm-x86/alternative.h | 2 ++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 65c7857a90d..de240ba2e28 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 5dd58136ef0..2e060c58b86 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 1f6a9ca1012..f6aa18eadf7 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. * -- GitLab From 3c1720f00bb619302ba19d55986ab565e74d06db Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0122/2509] 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 --- arch/x86/kernel/ftrace.c | 183 +++++++-------------------------------- include/linux/ftrace.h | 18 ++-- kernel/trace/ftrace.c | 154 +++++++++++++++++++++++++++++++- 3 files changed, 192 insertions(+), 163 deletions(-) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 2e060c58b86..b69795efa22 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 ccd8537dbdb..d509ad6c9cb 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; -- GitLab From d61f82d06672f57fca410da6f7fffd15867db622 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0123/2509] 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 --- arch/x86/kernel/entry_32.S | 47 +++++++++- arch/x86/kernel/entry_64.S | 67 +++++++++++++- arch/x86/kernel/ftrace.c | 41 ++++++++- include/linux/ftrace.h | 7 +- kernel/trace/ftrace.c | 183 +++++++++++++++++++++---------------- 5 files changed, 261 insertions(+), 84 deletions(-) diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f47b9b5440d..e6517ce0b82 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 f046e0c6488..fe25e5febca 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 b69795efa22..9f44623e007 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 d509ad6c9cb..b0dd0093058 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 f6d9af3bf66..88544f9bc0e 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; -- GitLab From 5072c59fd45e9976d02ee6f18c7336ef97623cbc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0124/2509] 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 --- include/linux/ftrace.h | 4 +- kernel/trace/ftrace.c | 527 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 513 insertions(+), 18 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b0dd0093058..f5911d2d42c 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; -- GitLab From 4c11d7aed389375253b59e2b1865eec96663c65d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0125/2509] 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 --- kernel/trace/trace.c | 245 +++++++++++++++++++++++++++++++++---------- kernel/trace/trace.h | 8 +- 2 files changed, 195 insertions(+), 58 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1b8eca7650d..d7ad030a4c4 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 3173a93561d..83e257e3808 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); -- GitLab From f43fdad8627fec2d21df92799b254dceb66c9c3c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:43 +0200 Subject: [PATCH 0126/2509] 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 --- arch/x86/kernel/machine_kexec_32.c | 4 ++++ arch/x86/kernel/machine_kexec_64.c | 4 ++++ include/linux/ftrace.h | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index d0b234c9fc3..88923fd7a6f 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 576a03db451..1558fdc174f 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 f5911d2d42c..a42390c1d6e 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)) -- GitLab From 5568b139f4d196273958ae2947a736fdf1ffeece Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0127/2509] 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 --- lib/smp_processor_id.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index e555ab62fba..3b4dc098181 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; } -- GitLab From 361943ad0ba3f16e66859e30a408915e008ba91e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0128/2509] 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 --- kernel/trace/trace_irqsoff.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 8b1231633dc..bd3f8819830 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); -- GitLab From 0764d23cf066c52de42b653144605b481d3fbdbc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0129/2509] 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 --- kernel/lockdep.c | 23 ++++++++++++----------- kernel/spinlock.c | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/kernel/lockdep.c b/kernel/lockdep.c index e21924365ea..ac46847ba0c 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 ae28c824512..a1fb54c93cd 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[]; -- GitLab From 18cef379d30f5ded20cc31d7f2d342639d39919d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0130/2509] 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 --- kernel/trace/trace.c | 4 ++-- kernel/trace/trace_sched_switch.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d7ad030a4c4..9175ce91b8f 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 3e4771d3b89..2715267be46 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) -- GitLab From 89b2f97819dd074297bbe3e19eaa4afcc98845ad Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0131/2509] 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 --- kernel/trace/trace.c | 6 +++++- kernel/trace/trace_irqsoff.c | 27 +++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9175ce91b8f..95966561ba3 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 bd3f8819830..74165f611f3 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) -- GitLab From 57f50be14d57b0dbf88dd019e7bb0ff3a3dc7b81 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0132/2509] ftrace: fix max latency Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 95966561ba3..9bad2379115 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) { -- GitLab From e1c08bdd9fa73e44096e5a82c0d5928b04ab02c8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0133/2509] ftrace: force recording Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 4 ++++ kernel/trace/ftrace.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a42390c1d6e..2c1670c6523 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 97d5cb7b7e7..4facf5ceeb8 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; } -- GitLab From 60a11774b38fef1ab90b18c5353bd1c7c4d311c8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: [PATCH 0134/2509] ftrace: add self-tests Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 13 + kernel/trace/trace.c | 63 ++++- kernel/trace/trace.h | 31 +++ kernel/trace/trace_functions.c | 3 + kernel/trace/trace_irqsoff.c | 9 + kernel/trace/trace_sched_switch.c | 3 + kernel/trace/trace_sched_wakeup.c | 3 + kernel/trace/trace_selftest.c | 415 ++++++++++++++++++++++++++++++ 8 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 kernel/trace/trace_selftest.c diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index cad9db1dee0..3f73a171024 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 9bad2379115..f6d026f17db 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 83e257e3808..88edbf1f678 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 82988c5336e..5d8ad7a0960 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 74165f611f3..14183b8f79c 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 2715267be46..6c9284103a6 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 7c3ccefcf4c..3d10ff01f80 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 00000000000..ef4d3cc009f --- /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 */ -- GitLab From c7aafc549766b87819285d3480648fc652a47bc4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0135/2509] ftrace: cleanups factor out code and clean it up. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 2 +- kernel/trace/ftrace.c | 8 +- kernel/trace/trace.c | 144 +++++++++++++++++++----------- kernel/trace/trace.h | 8 +- kernel/trace/trace_irqsoff.c | 32 +++---- kernel/trace/trace_sched_wakeup.c | 18 ++-- kernel/trace/trace_selftest.c | 25 +++--- 7 files changed, 134 insertions(+), 103 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 2c1670c6523..953a36d6a19 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 4facf5ceeb8..6d4d2e86deb 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 f6d026f17db..61d2f022886 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 88edbf1f678..cc1d34b8b77 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 14183b8f79c..2dfebb67fdf 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 3d10ff01f80..688df965f3f 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 ef4d3cc009f..c01874c3b1f 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; } -- GitLab From 7bd2f24c2f769e3f8f1d4fc8b9fddf689825f6a7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0136/2509] ftrace: add README make it easier for newbies to find their way around. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 61d2f022886..c736dd2e068 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, -- GitLab From 77a2b37d227483fe52aead242652aee406c25bf0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0137/2509] 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 --- include/linux/ftrace.h | 2 + kernel/trace/ftrace.c | 19 ++++++ kernel/trace/trace_selftest.c | 113 ++++++++++++++++++++++++++++++++-- 3 files changed, 130 insertions(+), 4 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 953a36d6a19..a842d96c634 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 6d4d2e86deb..5e9389faaf7 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 c01874c3b1f..4c8a1b2d823 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 */ -- GitLab From 4e3c3333f3bd7eedfd21b1155b3c7cd24fc7f754 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0138/2509] 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 --- kernel/trace/trace.c | 75 ++++++++++++++++++++++++++++++++------------ kernel/trace/trace.h | 9 +++++- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c736dd2e068..8755a437048 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 cc1d34b8b77..5df8ff2b84a 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); -- GitLab From 08bafa0efcf29fe18ec39c2147077b597368b018 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0139/2509] 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 --- kernel/trace/trace_selftest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 4c8a1b2d823..a6f1ed75f83 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; } -- GitLab From 1d4db00a5e30c7b8f8dc2a1b19e886fd942be143 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0140/2509] 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 --- kernel/trace/trace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8755a437048..6580e7ed04b 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 -- GitLab From 93a588f459da134be6ab17c4104e28441beb0d22 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: [PATCH 0141/2509] 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 --- kernel/trace/trace.c | 103 +++++++++++++++++++++++++------------------ kernel/trace/trace.h | 6 ++- 2 files changed, 65 insertions(+), 44 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6580e7ed04b..777b859e1c2 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 5df8ff2b84a..0ce127455b4 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; -- GitLab From 214023c3d13a71525e463b5e54e360b926b4dc90 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0142/2509] 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 --- kernel/trace/trace.c | 202 ++++++++++++++++++++++++++++--------------- kernel/trace/trace.h | 6 ++ 2 files changed, 140 insertions(+), 68 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 777b859e1c2..d39f4faec7c 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 0ce127455b4..f5b32ca0b45 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; -- GitLab From b3806b4316306dc9c542eff6c23d7d42918f3504 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0143/2509] 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 --- kernel/trace/trace.c | 353 +++++++++++++++++++++++++++++++++++++------ kernel/trace/trace.h | 2 + 2 files changed, 309 insertions(+), 46 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d39f4faec7c..a40687a4413 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 f5b32ca0b45..29a7ea59de5 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]; }; -- GitLab From d4c5a2f5870939d837293de87b41dda0012a4572 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0144/2509] 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 --- kernel/trace/trace.c | 8 +++----- kernel/trace/trace.h | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a40687a4413..b3811ca7407 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 29a7ea59de5..b0408356f0e 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: */ -- GitLab From 4bf39a9411a4ce8712954e03a9bd1592ee345919 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0145/2509] ftrace: cleanups no code changed. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/ftrace.c | 5 ++- kernel/trace/trace.c | 72 +++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5e9389faaf7..97c40865a93 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 b3811ca7407..4550afda960 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) -- GitLab From 750ed1a40783432d0dcb0e6c2e813a12615d7664 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0146/2509] ftrace: timestamp syncing, prepare rename and uninline now() to ftrace_now(). Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/ftrace.c | 4 ++-- kernel/trace/trace.c | 7 ++++++- kernel/trace/trace.h | 5 +---- kernel/trace/trace_functions.c | 2 +- kernel/trace/trace_irqsoff.c | 6 +++--- kernel/trace/trace_sched_switch.c | 2 +- kernel/trace/trace_sched_wakeup.c | 4 ++-- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 97c40865a93..a15e068535f 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 4550afda960..e3778ab0d3f 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 b0408356f0e..30cad677e9d 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 5d8ad7a0960..e5d34b78fc9 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 2dfebb67fdf..d2a6e6f1ad2 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 6c9284103a6..8d656672da9 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 688df965f3f..b7df825c3af 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: -- GitLab From 53c37c17aafcf50f7c6fddaf01dda8f9d7e31ddf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0147/2509] 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 --- kernel/trace/trace.c | 54 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e3778ab0d3f..9a931c7c2da 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; -- GitLab From cdd31cd2d7a0dcbec2cce3974f7129dd4fc8c879 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0148/2509] ftrace: remove-idx-sync remove idx syncing - it's expensive on SMP. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 40 +++++----------------------------------- kernel/trace/trace.h | 2 -- 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9a931c7c2da..ce8ceb8aea6 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 30cad677e9d..27fa2d06f49 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; -- GitLab From 8c523a9d82dbc4f3f7d972df8c0f1eacd83d0d55 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: [PATCH 0149/2509] ftrace: clean-up-pipe-iteration Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ce8ceb8aea6..42f1926acf7 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) { -- GitLab From f9896bf30928922a3913a3810a4ab7908da6cfe7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0150/2509] ftrace: add raw output Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 63 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 42f1926acf7..bebd263f582 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; -- GitLab From cb0f12aae8d085140d37ada351aa5a8e76c3f9b0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0151/2509] ftrace: bin-output Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bebd263f582..d78cbc4fc51 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); -- GitLab From f0a920d5752e1788c0cba2add103076bcc0f7a49 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0152/2509] ftrace: add trace_special() for ad-hoc tracing. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace.h | 15 +++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d78cbc4fc51..fa13059eb46 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 }; @@ -700,6 +701,22 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, spin_unlock(&data->lock); } +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, @@ -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 27fa2d06f49..7bdfef35c05 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -25,6 +25,15 @@ struct ctx_switch_entry { unsigned char next_prio; }; +/* + * 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); -- GitLab From dcb6308f2b56720599f6b9d5a01c33e67e69bde4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0153/2509] ftrace, locking fix should be an irq-safe lock ... Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fa13059eb46..70f94fa92c1 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 { -- GitLab From 088b1e427dbba2af93cb6a7d39258c10ff58dd27 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0154/2509] 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 --- kernel/trace/trace.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 70f94fa92c1..c56fc5e6013 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); -- GitLab From 37ad508419f0fdfda7b378756eb1f35cfd26d96d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0155/2509] 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 --- include/linux/ftrace.h | 7 ++++--- kernel/trace/ftrace.c | 45 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a842d96c634..61e757bd235 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) -- GitLab From 4eebcc81a33fbc45e28542b50197ed7b3c486d90 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0156/2509] 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 --- include/linux/ftrace.h | 3 + kernel/trace/ftrace.c | 112 +++++++++++++++++++++++++++++++--- kernel/trace/trace_selftest.c | 4 ++ 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 61e757bd235..4650a3160b7 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 8e02aa690b2..ff42345dd78 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,8 +1283,30 @@ 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 a6f1ed75f83..85715b86a34 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 */ -- GitLab From 26994ead1fc8cced63f17e9848edc1771036664e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0157/2509] 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 --- kernel/trace/trace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c56fc5e6013..3dc6eac85b1 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); -- GitLab From 0fd9e0dac9026df09986a4b201518ae015814aef Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0158/2509] ftrace: use cpu clock again Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 54 +------------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3dc6eac85b1..d74c039305a 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; -- GitLab From 2e0f57618529a2739a5e1570e6c445c9c966b595 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0159/2509] ftrace: build fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 111 ++++++++++++++++++++------------- kernel/trace/trace_functions.c | 2 +- 2 files changed, 67 insertions(+), 46 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d74c039305a..71b25b79b3d 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; @@ -650,6 +609,14 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, spin_unlock_irqrestore(&data->lock, irq_flags); } +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 e5d34b78fc9..69a0eb00a0a 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" -- GitLab From 5e3ca0ec76fce92daa4eed0d02de9c79b1fe3920 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0160/2509] ftrace: introduce the "hex" output method Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 93 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 71b25b79b3d..6974b212e93 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); -- GitLab From 2577046740fe6d77864128c6187c11125c2449ea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0161/2509] 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 --- kernel/trace/trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6974b212e93..958c4d77a67 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 */ -- GitLab From aeaee8a2c9cb4489f166ca0e39c568e8254faaa6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0162/2509] ftrace: build fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 4650a3160b7..08fbef1744c 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 -- GitLab From 2a2cc8f7c4d0dfd75720867f7dc58d24f075edfc Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Pedersen Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0163/2509] ftrace: allow the event pipe to be polled Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 958c4d77a67..d041578affd 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, }; -- GitLab From 6fb44b717c10ecf37beaaebd312f3afa93fed714 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0164/2509] 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 --- kernel/trace/trace.c | 8 ++++---- kernel/trace/trace.h | 5 +++++ kernel/trace/trace_irqsoff.c | 10 +++++----- kernel/trace/trace_sched_wakeup.c | 5 +++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d041578affd..9022c357032 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 7bdfef35c05..faf9f67246a 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 d2a6e6f1ad2..3269f4ff517 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 b7df825c3af..3549e4154f1 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); -- GitLab From 9ff9cdb2d3b0971f89e899b3420aadd91bddc215 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:50 +0200 Subject: [PATCH 0165/2509] ftrace: cleanups clean up recent code. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/ftrace.c | 5 +++-- kernel/trace/trace_irqsoff.c | 2 +- kernel/trace/trace_selftest.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ff42345dd78..425b1fec3d8 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 3269f4ff517..2ac0d09db6f 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 85715b86a34..546307de6e3 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: -- GitLab From caf8cdebfb6c1cff50ea8077f1a07c2333d6d1fd Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:50 +0200 Subject: [PATCH 0166/2509] 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 --- kernel/trace/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 425b1fec3d8..57350cbd1f6 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, -- GitLab From 3594136ad67a54d77bcb2547e70011754a2f91d5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:50 +0200 Subject: [PATCH 0167/2509] 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 --- lib/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Makefile b/lib/Makefile index 74b0cfb1fcc..6ca9e6ee1e3 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 -- GitLab From b53dde9d34f2df396540988ebc65c33400f57b04 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0168/2509] ftrace: disable -pg for the tracer itself Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 3fec653d653..c25a6cd6a52 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 -- GitLab From e309b41dd65aa953f86765eeeecc941d8e1e8b8f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0169/2509] 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 --- kernel/trace/ftrace.c | 66 +++++++++++----------- kernel/trace/trace.c | 94 +++++++++++++++---------------- kernel/trace/trace.h | 6 +- kernel/trace/trace_functions.c | 12 ++-- kernel/trace/trace_irqsoff.c | 40 ++++++------- kernel/trace/trace_sched_switch.c | 12 ++-- kernel/trace/trace_sched_wakeup.c | 28 ++++----- kernel/trace/trace_selftest.c | 2 +- 8 files changed, 130 insertions(+), 130 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 57350cbd1f6..281d97a3208 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 9022c357032..f5898051fdd 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 faf9f67246a..2b7352bf1ce 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 69a0eb00a0a..4165d34bd28 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 2ac0d09db6f..7a4dc014b8a 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 8d656672da9..b738eaca1db 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 3549e4154f1..662679c78b6 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 546307de6e3..85715b86a34 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: -- GitLab From 57422797dc009fc83766bcf230d29dbe6e08e21e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0170/2509] ftrace: add wakeup events to sched tracer Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 42 ++++++++++++++++++++++++++++--- kernel/trace/trace.h | 12 +++++++++ kernel/trace/trace_sched_switch.c | 36 ++++++++++++++++++++++++++ kernel/trace/trace_sched_wakeup.c | 2 +- kernel/trace/trace_selftest.c | 1 + 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f5898051fdd..192c1354a7e 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 2b7352bf1ce..90e0ba0f6eb 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 b738eaca1db..8b1cf1a3aee 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 662679c78b6..87fa7b253b5 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 85715b86a34..39dd452647d 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; -- GitLab From 86387f7ee5d3273ff4859e2c64ce656639b6ca65 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0171/2509] ftrace: add stack tracing Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 2 + kernel/trace/Kconfig | 1 + kernel/trace/trace.c | 103 ++++++++++++++++++++++++++++++++++------- kernel/trace/trace.h | 11 +++++ 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 08fbef1744c..0d3714e7110 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 3f73a171024..eb1988ed84b 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 192c1354a7e..b4b1b4fe99f 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 90e0ba0f6eb..387bdcf45e2 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -34,6 +34,16 @@ struct special_entry { unsigned long arg3; }; +/* + * 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; }; }; -- GitLab From 8ac0fca4ccb355ce50471d7aa3f10f5900b28b95 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0172/2509] ftrace: sched tracer fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/sched.h | 6 ------ kernel/sched.c | 2 +- kernel/trace/trace_sched_wakeup.c | 13 +++---------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 6e26f1fdbfe..05744f9cb09 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 328494e28df..53ab1174664 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 87fa7b253b5..2a012423f9d 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); } -- GitLab From 4c1f4d4f0175129934d5dbc19a39296430937a05 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: [PATCH 0173/2509] ftrace: make nostacktrace the default Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b4b1b4fe99f..0e4b7119e26 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); -- GitLab From 4e65551905fb0300ae7e667cbaa41ee2e3f29a13 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0174/2509] ftrace: sched tracer, trace full rbtree Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/sched.h | 32 +++++++++++++----- kernel/sched.c | 35 ++++++++++++++++++-- kernel/trace/trace.c | 55 +++++++++++++------------------ kernel/trace/trace.h | 14 ++++++++ kernel/trace/trace_sched_switch.c | 24 +++++++++----- 5 files changed, 108 insertions(+), 52 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 05744f9cb09..652d380ae56 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 53ab1174664..b9208a0e33a 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 0e4b7119e26..65173b14b91 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 387bdcf45e2..75e23747567 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 8b1cf1a3aee..12658b3f2b2 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): -- GitLab From 24cd5d111e8c713e62cda7ca1d01232402e3d3c9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0175/2509] ftrace: trace curr/next tasks Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/sched.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index b9208a0e33a..673b588b713 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)) -- GitLab From 017730c11241e26577673eb9d957cfc66172ea91 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0176/2509] ftrace: fix wakeups Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/sched.h | 2 ++ kernel/sched.c | 18 ++++++++++++++++++ kernel/trace/trace.c | 15 +++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 652d380ae56..a3970b56375 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 673b588b713..9ca4a2e6a23 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 65173b14b91..2ca9d66aa74 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 -- GitLab From 1a3c3034336320554a3342572dae98d69e054fc7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0177/2509] ftrace: fix __trace_special() Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/sched.h | 20 ++++++++++++-------- kernel/trace/trace.c | 4 ---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index a3970b56375..5b186bed54b 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 2ca9d66aa74..65d2c0a61ed 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, -- GitLab From 4ac3ba41d372e3a9e420b36bc43589662b188a14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0178/2509] ftrace: trace scheduler rbtree Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 1 + kernel/trace/trace.h | 1 + kernel/trace/trace_sched_switch.c | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 65d2c0a61ed..06380dc1ebe 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 75e23747567..a52015702a2 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 12658b3f2b2..5555b906a66 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); -- GitLab From c7078de1aaf562a31b20984409c38cc1b40fa8a3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0179/2509] ftrace: add tracing_cpumask Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 78 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 06380dc1ebe..18f0ab88ca8 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) -- GitLab From 36dfe9252bd4c9b55e8454363fb7e444c92c5030 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: [PATCH 0180/2509] ftrace: make use of tracing_cpumask Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 95 +++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 18f0ab88ca8..3ae17e254fc 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); -- GitLab From d9af56fbd8b37181bffaad060f74aa2e17382874 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0181/2509] ftrace: fix cmdline tracing Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sched_switch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 5555b906a66..5a217e86358 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); /* -- GitLab From 442e544ce52d4415a024920b84fb95c5f9aa0855 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0182/2509] ftrace: iter ctrl fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3ae17e254fc..688b4cf72d9 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; -- GitLab From f29c73fe3404f8799ed57aaf48859e0b55fc071f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0183/2509] ftrace: include cpu in stacktrace Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 688b4cf72d9..3a4032492fc 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: -- GitLab From 36fc25a9f48deacd8aa08cd2d1c186a4e412604f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0184/2509] ftrace: sched tree fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/sched.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 9ca4a2e6a23..3bc7c536299 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); } } -- GitLab From 88a4216c3ec4281fc7e6725cc3a3ccd01fb1aa14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0185/2509] ftrace: sched special Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/sched.h | 6 ++++++ kernel/sched_fair.c | 3 +++ kernel/trace/trace.c | 6 +++--- kernel/trace/trace_sched_switch.c | 24 ++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 5b186bed54b..360ca99033d 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 e24ecd39c4b..dc1856f1079 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 3a4032492fc..b87a2641489 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 5a217e86358..bddf676914e 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; -- GitLab From bac524d3f3dfeffa3a9d44f2c64035b88bcaacb4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0186/2509] ftrace: trace next state Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 35 +++++++++++++++++++++++++---------- kernel/trace/trace.h | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b87a2641489..b63fe909f87 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 a52015702a2..96951a8d09a 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; }; /* -- GitLab From 5429db2d26a59903c81a4f6c6dae7eb9daaea5fc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 May 2008 21:20:53 +0200 Subject: [PATCH 0187/2509] ftrace: fix wakeup callback Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index 3bc7c536299..1ec3fb2efee 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; -- GitLab From 694379e9ed4f2f6babe111bf001c69e2e263338b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0188/2509] ftrace: make it more available in the Kconfig Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index eb1988ed84b..ebc158e6d59 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 -- GitLab From 8f96da02c14d722ad9a3713cd7273ce28c9036ad Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0189/2509] 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 --- kernel/trace/trace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b63fe909f87..736dcfb3ed0 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 -- GitLab From 4fe8c3048cd8280a54256bca9cac2007bd546c33 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0190/2509] 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 --- kernel/trace/trace_irqsoff.c | 26 ++++++++++++++------------ kernel/trace/trace_sched_wakeup.c | 13 ------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 7a4dc014b8a..d0c1748b1e2 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 2a012423f9d..5948011006b 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); -- GitLab From 06fa75ab566c50e01bfd7b055bde85cf9b1bc98a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0191/2509] 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 --- kernel/trace/trace_selftest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 39dd452647d..92f4acb7740 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; } -- GitLab From d05cdb25d80f06f77aa6bddb53cd1390d4d91a0b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0192/2509] 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 --- kernel/trace/Makefile | 4 ++++ kernel/trace/trace.h | 2 ++ kernel/trace/trace_selftest.c | 6 ------ kernel/trace/trace_selftest_dynamic.c | 7 +++++++ 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 kernel/trace/trace_selftest_dynamic.c diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index c25a6cd6a52..d9efbbfa2bd 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 96951a8d09a..98cbfd05d75 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 92f4acb7740..83e55a2000c 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 00000000000..54dd77cce5b --- /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; +} -- GitLab From 4d9493c90f8e6e1b164aede3814010a290161abb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0193/2509] ftrace: remove add-hoc code Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/sched.c | 47 ------------------------------- kernel/sched_fair.c | 3 -- kernel/trace/trace_sched_switch.c | 10 ++----- 3 files changed, 2 insertions(+), 58 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 1ec3fb2efee..ad95cca4e42 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 dc1856f1079..e24ecd39c4b 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 bddf676914e..5671db0e182 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); -- GitLab From c5f888cae49dfe3e86d9d1e0dab2b63ceb057be3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0194/2509] 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 --- kernel/trace/trace_irqsoff.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index d0c1748b1e2..761f3ec66c5 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) -- GitLab From 92205c2343527a863d660360599a4bf8cede77b0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0195/2509] 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 --- kernel/trace/trace.c | 51 ++++++++++++++++++++++++++------------------ kernel/trace/trace.h | 2 +- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 736dcfb3ed0..3009aafa4dd 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 98cbfd05d75..25cba28eb9b 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: */ -- GitLab From 9d0a420b737f72d84fabebf29634d800cbf54538 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0196/2509] 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 --- lib/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Makefile b/lib/Makefile index 6ca9e6ee1e3..d97ad1100b6 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 -- GitLab From 1d09daa55d2e9bab7e7d30f0d05e5a7bc60b2a4a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0197/2509] 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 --- kernel/Makefile | 8 ++++++++ kernel/lockdep.c | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 7e344e7b0cb..d2f80ea4cd9 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 ac46847ba0c..90a440cbd6d 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; -- GitLab From c1d2327b36f2261ffa8ff7227321ba900c7eee7f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0198/2509] ftrace: restrict tracing to HAVE_FTRACE architectures Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index ebc158e6d59..f3005717bcd 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 -- GitLab From 07a267cdd2fd7d1de9455b1e36a1635ace7276c7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: [PATCH 0199/2509] 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 --- kernel/trace/ftrace.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 281d97a3208..40f64f7cd85 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; -- GitLab From d15f57f23eaba975309a153b23699cd0c0236974 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0200/2509] 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 --- kernel/trace/trace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3009aafa4dd..ea11f4ebfae 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); -- GitLab From 30afdcb1de0a37a2086145a82ca3febebe47d019 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0201/2509] 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 --- kernel/trace/trace_selftest.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 83e55a2000c..395274e783b 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; -- GitLab From a56be3fe2f65f9f776e727bfd382e35db75911d6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0202/2509] 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 --- arch/x86/kernel/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 9f44623e007..498608c015f 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) -- GitLab From 8f0f996e80b980fba07d11961d96a5fefb60976a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0203/2509] 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 --- arch/x86/mm/init_32.c | 4 ++++ arch/x86/mm/init_64.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index ec30d10154b..f96eca21ad8 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 32ba13b0f81..41824e776b6 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(); -- GitLab From 86069782d62e731b4835a0cf8eb7d1d0e17cf306 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0204/2509] 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 --- arch/x86/Kconfig.debug | 8 ++++++ arch/x86/mm/fault.c | 56 ++++++++++++++++++++++++++++++++++++++++ include/asm-x86/kdebug.h | 9 +++++++ 3 files changed, 73 insertions(+) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index ac1e31ba479..9431a839984 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 fd7e1798c75..343f5c1aacc 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 96651bb59ba..a80f2d6cc73 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 -- GitLab From 72829bc3d63cdc592d8f7dd86ad3b3fe8900fb74 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 21:37:28 +0200 Subject: [PATCH 0205/2509] 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 --- kernel/trace/trace.c | 24 ++++++++---------------- kernel/trace/trace.h | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ea11f4ebfae..0eef0503feb 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 25cba28eb9b..b0ca7473671 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; -- GitLab From d17d969160c18b631a19c2b34d260691402650f8 Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0206/2509] 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 --- kernel/trace/trace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0eef0503feb..9197782d15c 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, -- GitLab From 8487c23765b6e0444ec6b5f1530766d63fe68e35 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0207/2509] 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 --- kernel/trace/trace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9197782d15c..fd4ecc29200 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: -- GitLab From b5685aede3b7b65e72ddc73b951aa1f70798a614 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0208/2509] 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 --- kernel/trace/trace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fd4ecc29200..d141fc98f3a 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; /* -- GitLab From 845279972f1736c3463c9cebd1bad92a0a347176 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0209/2509] 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 --- kernel/trace/trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d141fc98f3a..2af940433e9 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 -- GitLab From 2dc8f09571a61d9cb3dc47bba6608689dfe15d16 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0210/2509] 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 --- kernel/trace/trace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2af940433e9..3b4eaf36ed5 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: -- GitLab From 05bd68c514579e007b46e4fa0461b78416a3f4c2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0211/2509] 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 --- kernel/trace/trace_selftest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 395274e783b..a5f6001c333 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); -- GitLab From a98a3c3fde3ae7614f19758a043691b6f59dac53 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0212/2509] 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 --- kernel/trace/trace.c | 145 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3b4eaf36ed5..4723e012151 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); -- GitLab From bb065afb8ebd07a03155502dba29ebf0f6fe67e8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0213/2509] 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 --- kernel/lockdep.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 90a440cbd6d..65548eff029 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; } -- GitLab From 93dcc6ea096c51cc30ad0f6647ed05fead2439bf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0214/2509] ftrace: simplify hexprint simplify hex to ascii conversion. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4723e012151..627e39936ea 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); } -- GitLab From afc2abc0ae4265730a0fc48618012193a09a1d10 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0215/2509] ftrace: cleanups no code changed. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 627e39936ea..d6b60576f99 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); -- GitLab From cffae437cdfbc8a5370d38cefbff1dfe34dad6ca Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0216/2509] 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 --- kernel/trace/trace.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d6b60576f99..0a367362ba2 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; -- GitLab From c6caeeb142cd3a03c46107aac45c8effc02bbadb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0217/2509] 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 --- kernel/trace/trace.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0a367362ba2..290e9da7aa9 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) -- GitLab From ab46428c6969d50ecf6f6e97b7a84abba6274368 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0218/2509] 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 --- kernel/trace/trace.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 290e9da7aa9..5da391c5fb0 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); -- GitLab From 4fcdae83cebda24b519a89d3dd976081fff1ca80 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0219/2509] 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 --- kernel/trace/trace.c | 135 ++++++++++++++++++++++++++++++++++++++++++- kernel/trace/trace.h | 7 +++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5da391c5fb0..a102b11eacf 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 b0ca7473671..21c29ee13e5 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, -- GitLab From 25b0b44a1c732ccfc58095cdd8438955a0a19fff Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: [PATCH 0220/2509] 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 --- kernel/trace/trace.c | 7 ++++++- kernel/trace/trace.h | 2 ++ kernel/trace/trace_functions.c | 2 ++ kernel/trace/trace_sched_switch.c | 7 +++++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a102b11eacf..1281969103b 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 21c29ee13e5..8991c5efcc7 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 4165d34bd28..0a084656d7c 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 5671db0e182..a3376478fc2 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; } -- GitLab From 72b59d67f80983f7bb587b086fb4cb1bc95263a4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:01 +0200 Subject: [PATCH 0221/2509] 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 --- arch/x86/mm/init_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 41824e776b6..295be1d07b8 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(); -- GitLab From 53d0aa773053ab18287781e25d52c5faf9e0e09e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: [PATCH 0222/2509] 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 --- kernel/trace/trace.c | 16 +++++++++++----- kernel/trace/trace.h | 6 +++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1281969103b..b9126ef46a9 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 8991c5efcc7..c1ec134ac35 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; -- GitLab From 107bad8bef5ab2c3a3bff7648c18c9dc3abdc13b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: [PATCH 0223/2509] 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 --- kernel/trace/trace.c | 38 +++++++++++++++++++++++++++++++------- kernel/trace/trace.h | 5 +++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b9126ef46a9..32f9106d612 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 c1ec134ac35..ee53d706066 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]; -- GitLab From 2f1dafe50cc4e58a239fd81bd47f87f32042a1ee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:01 +0200 Subject: [PATCH 0224/2509] 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 --- arch/x86/kernel/alternative.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index de240ba2e28..2763cb37b55 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 -- GitLab From 4823ed7eadf35e4b57ce581327e21d39585f1f32 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: [PATCH 0225/2509] 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 --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 32f9106d612..49e16630628 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 -- GitLab From 9fe068e92f6290e89e19adc521441661a1229f00 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0226/2509] ftrace: trace faster Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 49e16630628..ca0d6ff74c1 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); -- GitLab From a4feb8348b62fe76a63cdb5569f5c920f5283c06 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0227/2509] ftrace: special stacktrace Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 47 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ca0d6ff74c1..c232d8248a0 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, @@ -856,6 +833,30 @@ void __trace_stack(struct trace_array *tr, save_stack_trace(&trace); } +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, -- GitLab From 2bb6f8d6389cbfadd657e7dc069f6986abf35e4f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0228/2509] 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 --- kernel/trace/ftrace.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 40f64f7cd85..af5ad8949ab 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) -- GitLab From 6c6c27969a4c6024e6c8838829546c02aaddca18 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0229/2509] 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 --- kernel/trace/trace.c | 73 ++++++++++++++++++++++---------------------- kernel/trace/trace.h | 3 ++ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c232d8248a0..82ced406aac 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 ee53d706066..8845033ab49 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; -- GitLab From 3eefae994d9224fb7771a3ddb683868363c23510 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:04 +0200 Subject: [PATCH 0230/2509] 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 --- include/linux/writeback.h | 2 ++ kernel/trace/trace.c | 38 ++++++++++++++++++++++++++++++++++++++ mm/page-writeback.c | 10 +++++++--- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f462439cc28..bd91987c065 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 82ced406aac..2824cf48cdc 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 789b6adbef3..b38f700825f 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; -- GitLab From dc102a8fae2d0d6bf5223fc549247f2e23959ae6 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:09 +0200 Subject: [PATCH 0231/2509] 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 --- include/linux/marker.h | 11 +++++------ kernel/marker.c | 30 ++++++++++++++---------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/linux/marker.h b/include/linux/marker.h index 430f6adf976..338533abb47 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 b5a9fe1d50d..1abfb923b76 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(); } -- GitLab From 0aa977f592f17004f9d1d545f2e1bb9ea71896c3 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:10 +0200 Subject: [PATCH 0232/2509] 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 --- include/linux/marker.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/include/linux/marker.h b/include/linux/marker.h index 338533abb47..1290653f924 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. -- GitLab From 5b82a1b08a00b2adca3d9dd9777efff40b7aaaa1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:10 +0200 Subject: [PATCH 0233/2509] 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 --- include/linux/sched.h | 32 ------ kernel/sched.c | 14 ++- kernel/trace/trace.h | 20 +--- kernel/trace/trace_sched_switch.c | 171 +++++++++++++++++++++++++----- kernel/trace/trace_sched_wakeup.c | 106 ++++++++++++++++-- 5 files changed, 255 insertions(+), 88 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 360ca99033d..c0b1c69b55c 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 ad95cca4e42..e2e985eeee7 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 8845033ab49..f5de0601b40 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 a3376478fc2..d25ffa5eaf2 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 5948011006b..5d2fb48e47f 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) -- GitLab From 74f4e369fc5b52433ad824cef32d3bf1304549be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:15 +0200 Subject: [PATCH 0234/2509] ftrace: stacktrace fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 8 ++++++++ kernel/semaphore.c | 2 ++ kernel/trace/trace.c | 4 ++-- kernel/trace/trace.h | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 0d3714e7110..017ab44d572 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 5c2942e768c..1a064adab65 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 2824cf48cdc..3271916ff03 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 f5de0601b40..c460e85e94e 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]; -- GitLab From aa5e5ceaf52a882a29d9b86531a20733f5116066 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 13 May 2008 22:06:56 -0700 Subject: [PATCH 0235/2509] 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 --- kernel/trace/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index af5ad8949ab..07b2a14943f 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)) -- GitLab From d05f5f9906740474eb768823004ffcd775b12ca6 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 13 May 2008 22:06:59 -0700 Subject: [PATCH 0236/2509] sparc64: add ftrace support. Signed-off-by: David S. Miller Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/sparc64/Kconfig | 1 + arch/sparc64/Kconfig.debug | 2 +- arch/sparc64/kernel/Makefile | 1 + arch/sparc64/kernel/ftrace.c | 99 ++++++++++++++++++++++++++++++++++++ arch/sparc64/lib/mcount.S | 58 +++++++++++++++++++-- 5 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 arch/sparc64/kernel/ftrace.c diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index eb36f3b746b..a480df6e601 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 6a4d28a4076..d6d32d178fc 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 ec4f5ebb1ca..418b5782096 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 00000000000..f449e6df6c4 --- /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 9e4534b485c..7735a7a6053 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 -- GitLab From 37135677e653537ffc6e7def679443272a1c03c3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 14 May 2008 08:10:31 +0200 Subject: [PATCH 0237/2509] 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 --- arch/x86/kernel/i386_ksyms_32.c | 9 ++++++++- arch/x86/kernel/x8664_ksyms_64.c | 11 +++++++++-- kernel/trace/ftrace.c | 3 --- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index deb43785e92..29999dbb754 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 f6c05d0410f..122885bc5f3 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 07b2a14943f..a3e47f43f8a 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; -- GitLab From 2d8b820b2e81954754277723379ae9ed5de316fa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 23 Feb 2008 16:55:50 +0100 Subject: [PATCH 0238/2509] ftrace: cleanups factor out code and clean it up. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/ftrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index a3e47f43f8a..89bd9a6f52e 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" -- GitLab From d49dbf33f0bf8748ee3662b973eb57e60525d622 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 16 May 2008 10:41:53 +0200 Subject: [PATCH 0239/2509] ftrace: fix include file dependency Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 017ab44d572..911d5d80b49 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 -- GitLab From 489f139614596cbc956a06f5e4bb41288e276fe3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 25 Feb 2008 13:38:05 +0100 Subject: [PATCH 0240/2509] ftrace: fix build bug Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/ftrace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 911d5d80b49..922e23d0196 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) -- GitLab From e0eca07badc023a675a61906020b397da20f07c3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 23:49:43 -0400 Subject: [PATCH 0241/2509] 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 --- include/asm-powerpc/hw_irq.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index ad8c9f7fd0e..f75a5fc64d2 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 */ /* -- GitLab From 4e491d14f2506b218d678935c25a7027b79178b1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 23:49:44 -0400 Subject: [PATCH 0242/2509] 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 --- arch/powerpc/Kconfig | 3 +- arch/powerpc/kernel/Makefile | 14 ++ arch/powerpc/kernel/entry_32.S | 130 ++++++++++++++++++ arch/powerpc/kernel/entry_64.S | 62 +++++++++ arch/powerpc/kernel/ftrace.c | 165 +++++++++++++++++++++++ arch/powerpc/kernel/io.c | 3 +- arch/powerpc/kernel/irq.c | 6 +- arch/powerpc/kernel/setup_32.c | 11 +- arch/powerpc/kernel/setup_64.c | 5 + arch/powerpc/platforms/powermac/Makefile | 5 + kernel/trace/trace_selftest.c | 11 +- 11 files changed, 405 insertions(+), 10 deletions(-) create mode 100644 arch/powerpc/kernel/ftrace.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3934e265940..62d034adbd4 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 2346d271fbf..f3f5e264143 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 0c8614d9875..0e6221889ca 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 c0db5b769e5..2c4d9e056ea 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 00000000000..5a4993fefa4 --- /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 e31aca9208e..1882bf419fa 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 2f73f705d56..6e01eb0a331 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 5112a4aa801..22f8e2bacd3 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 098fd96a394..277bf18cbbc 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 4d72c8f7215..89774177b20 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 a5f6001c333..3877dd9102f 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; -- GitLab From 656ee82cc855027b2e994ad218519b09fa652cc1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:29 -0400 Subject: [PATCH 0243/2509] 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 --- scripts/Makefile.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8e440233c27..ea48b82a370 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)) -- GitLab From 6ec562328fda585be2d7f472cfac99d3b44d362a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:30 -0400 Subject: [PATCH 0244/2509] 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 --- kernel/Makefile | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index d2f80ea4cd9..ca2433e8487 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 -- GitLab From 654e4787689faffdd2137fe91f59fd3ef3363ad2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:31 -0400 Subject: [PATCH 0245/2509] 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 --- lib/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index d97ad1100b6..4b836a53c08 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 -- GitLab From 7fa09f24b477ad41b821713eba757b3aa7a2864a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:32 -0400 Subject: [PATCH 0246/2509] 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 --- arch/x86/kernel/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index e142091524b..739d49acd2f 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: -- GitLab From 677aa9f77e8de3791b481a0cec6c8b84d1eec626 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 17 May 2008 00:01:36 -0400 Subject: [PATCH 0247/2509] 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 --- arch/powerpc/Kconfig | 1 + arch/sparc64/Kconfig | 1 + arch/x86/Kconfig | 1 + kernel/trace/Kconfig | 4 ++++ 4 files changed, 7 insertions(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 62d034adbd4..a5e9912e2d3 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 a480df6e601..fca9246470b 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 c742dfeb0db..fc86c54e791 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 f3005717bcd..5c2295b29f2 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 -- GitLab From f06c38103ea9dbca27c3f4d77f444ddefb5477cd Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0248/2509] ftrace: add sysprof plugin very first baby version. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 8 ++++ kernel/trace/Makefile | 1 + kernel/trace/trace_sysprof.c | 80 ++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 kernel/trace/trace_sysprof.c diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 5c2295b29f2..e101c9a85f0 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 d9efbbfa2bd..7aec123ec1d 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 00000000000..6c139bc1be7 --- /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); -- GitLab From 0075fa80305f3231a2d5df97b00d7f55a48ea27e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0249/2509] ftrace: extend sysprof plugin add per CPU hrtimers. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 67 +++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 6c139bc1be7..ba55b871b3d 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; } -- GitLab From 56a08bdcff20f0022bd9160c1093e56f763499aa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0250/2509] ftrace: extend sysprof plugin some more Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 80 ++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index ba55b871b3d..b1137c11ef8 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); -- GitLab From a6dd24f8d00cbccb560b19a723e6fb9bdfb20799 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0251/2509] ftrace: sysprof-plugin, add self-tests Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.h | 4 ++++ kernel/trace/trace_selftest.c | 28 ++++++++++++++++++++++++++++ kernel/trace/trace_sysprof.c | 6 +++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c460e85e94e..b2198bc830a 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 3877dd9102f..033a6fb2e5f 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 b1137c11ef8..b78f12f77fc 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 }; -- GitLab From 842af315e8b0adad58fc642eaa5e6f53525e0534 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: [PATCH 0252/2509] ftrace: sysprof plugin improvement add sample maximum depth. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index b78f12f77fc..7f6fcccffb8 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) -- GitLab From ef4ab15ff34fd9c65e92bee70f58e7179da881c5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0253/2509] 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 --- kernel/trace/Kconfig | 2 +- kernel/trace/trace_selftest.c | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e101c9a85f0..9b49526ac0b 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 033a6fb2e5f..5588ecc4098 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 */ -- GitLab From 9f6b4e3f4a24f2590f1c96f117fc45fbea9b0fa4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: [PATCH 0254/2509] ftrace: sysprof fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 7f6fcccffb8..f9a09fe705b 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); } -- GitLab From d618b3e6e50970a6248ac857653fdd49bcd3c045 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: [PATCH 0255/2509] ftrace: sysprof updates make the sample period configurable. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 3 ++ kernel/trace/trace.h | 2 ++ kernel/trace/trace_sysprof.c | 70 ++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3271916ff03..95b7c48a9a1 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 b2198bc830a..b7f85d9c80d 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 f9a09fe705b..19406236b67 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"); +} -- GitLab From ada6b835067dc022f11cdae1c313a3710d3d977c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:50:41 +0200 Subject: [PATCH 0256/2509] ftrace: remove notrace Remove the notrace annotations. The build logic takes care of that. Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 19406236b67..3b1e4ba9180 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); -- GitLab From 9caee613d3b860ae81b79370eeae9ac967c07536 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:55:54 +0200 Subject: [PATCH 0257/2509] ftrace: fix __trace_special() Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 3b1e4ba9180..76dd953eecc 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) -- GitLab From 5fc4511c756860149b81aead6eca5bdf5c438ea7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:58:21 +0200 Subject: [PATCH 0258/2509] ftrace: make it more available in the Kconfig Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 9b49526ac0b..e101c9a85f0 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 -- GitLab From cd2134b1dda92fd450e6a1e12b1c7960dd6a2178 Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Pedersen Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0259/2509] 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 --- kernel/trace/trace_sysprof.c | 89 ++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 76dd953eecc..ebcb66d054c 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: -- GitLab From 8a9e94c1fbfdac45a3b6811b880777c4116aa309 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: [PATCH 0260/2509] sysprof: update copyrights Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace_sysprof.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index ebcb66d054c..fe23d6dba7f 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 -- GitLab From cf3271a73b612a03da00681ecd9bfefab37c74c9 Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Date: Mon, 12 May 2008 05:28:50 +0200 Subject: [PATCH 0261/2509] 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 --- kernel/trace/trace_sysprof.c | 50 +++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index fe23d6dba7f..2301e1e7c60 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) -- GitLab From bfeeeeb991cf75081e6c2f74d44ae5da05b50a94 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 May 2008 21:21:14 +0200 Subject: [PATCH 0262/2509] 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 --- kernel/stacktrace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index b71816e47a3..0914d0cbc83 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]; -- GitLab From 8b7d89d02ef3c6a7c73d6596f28cea7632850af4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0263/2509] 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 --- arch/x86/Kconfig.debug | 27 ++ arch/x86/kernel/Makefile | 2 + arch/x86/kernel/init_task.c | 1 + arch/x86/kernel/mmiotrace/Makefile | 4 + arch/x86/kernel/mmiotrace/kmmio.c | 391 ++++++++++++++++ arch/x86/kernel/mmiotrace/kmmio.h | 58 +++ arch/x86/kernel/mmiotrace/mmio-mod.c | 527 ++++++++++++++++++++++ arch/x86/kernel/mmiotrace/pf_in.c | 489 ++++++++++++++++++++ arch/x86/kernel/mmiotrace/pf_in.h | 39 ++ arch/x86/kernel/mmiotrace/testmmiotrace.c | 77 ++++ include/linux/mmiotrace.h | 62 +++ 11 files changed, 1677 insertions(+) create mode 100644 arch/x86/kernel/mmiotrace/Makefile create mode 100644 arch/x86/kernel/mmiotrace/kmmio.c create mode 100644 arch/x86/kernel/mmiotrace/kmmio.h create mode 100644 arch/x86/kernel/mmiotrace/mmio-mod.c create mode 100644 arch/x86/kernel/mmiotrace/pf_in.c create mode 100644 arch/x86/kernel/mmiotrace/pf_in.h create mode 100644 arch/x86/kernel/mmiotrace/testmmiotrace.c create mode 100644 include/linux/mmiotrace.h diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9431a839984..7c6496e2225 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 739d49acd2f..a51ac153685 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 a4f93b4120c..027a5b6a12b 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 00000000000..d6905f7f981 --- /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 00000000000..8ba48f9c91b --- /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 00000000000..85b7f68a3b8 --- /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 00000000000..73561fe85f0 --- /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 00000000000..67ea520dde6 --- /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 00000000000..e05341a51a2 --- /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 00000000000..40e66b0e648 --- /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 00000000000..cb247825f3e --- /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 */ -- GitLab From 75bb88350e0501b3cf5ac096a1008757844414a9 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0264/2509] 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 --- arch/x86/kernel/mmiotrace/kmmio.c | 46 +++++++++++++++++++--------- arch/x86/kernel/mmiotrace/mmio-mod.c | 19 +++++++----- arch/x86/mm/pageattr.c | 1 + 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 8ba48f9c91b..28411dadb8b 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 73561fe85f0..e43947d218a 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 60bcb5b6a37..57970f2935c 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: -- GitLab From fe1ffafa80f6673101c6560c2bacfe3df10372ee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: [PATCH 0265/2509] 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 --- arch/x86/kernel/mmiotrace/mmio-mod.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index e43947d218a..0019dcdf615 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; -- GitLab From 63ffa3e456c1a9884a3ebac997d91e3fdae18d78 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0266/2509] x86 mmiotrace: comment about user space ABI Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/mmiotrace.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index cb247825f3e..6ec288f1fe2 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 */ -- GitLab From 10c43d2eb50c9a5ad60388b9d3c41c31150049e6 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0267/2509] 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 --- arch/x86/Kconfig.debug | 14 +++---- arch/x86/kernel/mmiotrace/kmmio.c | 14 +++---- arch/x86/mm/fault.c | 66 ++++++++++++++++--------------- include/asm-x86/kdebug.h | 12 +++--- 4 files changed, 52 insertions(+), 54 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 7c6496e2225..9491c0ae03a 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 28411dadb8b..e759f7c3878 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 343f5c1aacc..e9a086a1a9f 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 a80f2d6cc73..7063281040d 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 -- GitLab From f513638030ca384b0bace4df64f0b82f6ae1e4c6 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0268/2509] 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 --- arch/x86/kernel/mmiotrace/kmmio.c | 27 +++++----- arch/x86/kernel/mmiotrace/mmio-mod.c | 80 +++++++++++++++------------- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index e759f7c3878..5e239d0b846 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 0019dcdf615..f9c609266d8 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) { -- GitLab From 0fd0e3da4557c479b820b9a4a7afa25b4637ddf2 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0269/2509] 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 --- arch/x86/kernel/init_task.c | 1 - arch/x86/kernel/mmiotrace/Makefile | 8 +- arch/x86/kernel/mmiotrace/kmmio.c | 349 +++++++++++++++------- arch/x86/kernel/mmiotrace/kmmio.h | 58 ---- arch/x86/kernel/mmiotrace/mmio-mod.c | 81 +++-- arch/x86/kernel/mmiotrace/pf_in.c | 2 +- arch/x86/kernel/mmiotrace/testmmiotrace.c | 13 +- arch/x86/mm/fault.c | 59 +--- include/asm-x86/kdebug.h | 7 - include/linux/mmiotrace.h | 38 +++ 10 files changed, 335 insertions(+), 281 deletions(-) delete mode 100644 arch/x86/kernel/mmiotrace/kmmio.h diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 027a5b6a12b..a4f93b4120c 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 d6905f7f981..cf1e747b463 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 5e239d0b846..539a9b19588 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; } @@ -169,13 +220,25 @@ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) __flush_tlb_one(page); } +/* + * 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 85b7f68a3b8..00000000000 --- 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 f9c609266d8..e1a508588f0 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 67ea520dde6..efa1911e20c 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 40e66b0e648..5ecff578672 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 e9a086a1a9f..8c828a68d3b 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 7063281040d..96651bb59ba 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 6ec288f1fe2..d87a6cd8b68 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. -- GitLab From d61fc44853f46fb002228b18aa5f30db21fcd4ac Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0270/2509] 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 --- arch/x86/Kconfig.debug | 20 +- arch/x86/kernel/mmiotrace/Makefile | 2 +- arch/x86/kernel/mmiotrace/kmmio.c | 72 ++-- arch/x86/kernel/mmiotrace/mmio-mod.c | 397 ++++++++++++++-------- arch/x86/kernel/mmiotrace/testmmiotrace.c | 15 +- arch/x86/mm/ioremap.c | 9 +- include/linux/mmiotrace.h | 18 +- 7 files changed, 332 insertions(+), 201 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9491c0ae03a..aa0d6462b1f 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 cf1e747b463..dbcd8d50fb8 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 539a9b19588..efb46793308 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 e1a508588f0..738644061e4 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 5ecff578672..cfa60b227c8 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 71bb3159031..8927c878544 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 d87a6cd8b68..cb5efd0c7f5 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__ */ -- GitLab From f984b51e0779a6dd30feedc41404013ca54e5d05 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0271/2509] 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 --- arch/x86/Kconfig.debug | 3 +- arch/x86/kernel/mmiotrace/mmio-mod.c | 208 ++++----------------------- include/linux/mmiotrace.h | 6 + kernel/trace/Makefile | 1 + kernel/trace/trace_mmiotrace.c | 84 +++++++++++ 5 files changed, 123 insertions(+), 179 deletions(-) create mode 100644 kernel/trace/trace_mmiotrace.c diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index aa0d6462b1f..7e4b8494078 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 738644061e4..c7a67d7e482 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 cb5efd0c7f5..579b3b06c90 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 d9efbbfa2bd..c44a7dce908 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 00000000000..e4dd03cc5aa --- /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); +} -- GitLab From bd8ac686c73c7e925fcfe0b02dc4e7b947127864 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: [PATCH 0272/2509] 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 --- arch/x86/Kconfig.debug | 2 +- arch/x86/kernel/mmiotrace/mmio-mod.c | 140 ++++++++----------------- include/linux/mmiotrace.h | 85 +++++---------- kernel/trace/trace.c | 34 ++++++ kernel/trace/trace.h | 14 +++ kernel/trace/trace_mmiotrace.c | 151 ++++++++++++++++++++++----- 6 files changed, 238 insertions(+), 188 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 7e4b8494078..1d6de0d67f9 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 c7a67d7e482..62abc281a51 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 579b3b06c90..c88a9c197d2 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 3271916ff03..d14fe49e963 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 c460e85e94e..0ef9ef74c80 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 e4dd03cc5aa..3a12b1ad0c6 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(); } -- GitLab From 138295373ccf7625fcb0218dfea114837983bc39 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0273/2509] 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 --- arch/x86/kernel/mmiotrace/kmmio.c | 186 +++++++++++---------------- arch/x86/kernel/mmiotrace/mmio-mod.c | 3 - include/linux/mmiotrace.h | 2 - kernel/trace/trace_mmiotrace.c | 47 ++++++- 4 files changed, 120 insertions(+), 118 deletions(-) diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index efb46793308..cd0d95fe4fe 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 62abc281a51..8256546d49b 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 c88a9c197d2..dd6b64b160f 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 3a12b1ad0c6..361472b5788 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) -- GitLab From 801a175bf601f9a9d5e86e92dee9adeeb6625da8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0274/2509] mmiotrace: ftrace fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d14fe49e963..4dcc4e85c5d 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(); } -- GitLab From 49023168261a7f9a2fd4a1ca1adbfea922556015 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:58 +0200 Subject: [PATCH 0275/2509] mmiotrace: cleanup Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/mmiotrace/kmmio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index cd0d95fe4fe..3ad27b8504a 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); -- GitLab From ff3a3e9ba5e4273a8bc10570adab4a390fb90757 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0276/2509] x86 mmiotrace: move files into arch/x86/mm/. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/Makefile | 2 -- arch/x86/kernel/mmiotrace/Makefile | 4 ---- arch/x86/mm/Makefile | 5 +++++ arch/x86/{kernel/mmiotrace => mm}/kmmio.c | 0 arch/x86/{kernel/mmiotrace => mm}/mmio-mod.c | 0 arch/x86/{kernel/mmiotrace => mm}/pf_in.c | 0 arch/x86/{kernel/mmiotrace => mm}/pf_in.h | 0 arch/x86/{kernel/mmiotrace => mm}/testmmiotrace.c | 0 8 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 arch/x86/kernel/mmiotrace/Makefile rename arch/x86/{kernel/mmiotrace => mm}/kmmio.c (100%) rename arch/x86/{kernel/mmiotrace => mm}/mmio-mod.c (100%) rename arch/x86/{kernel/mmiotrace => mm}/pf_in.c (100%) rename arch/x86/{kernel/mmiotrace => mm}/pf_in.h (100%) rename arch/x86/{kernel/mmiotrace => mm}/testmmiotrace.c (100%) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a51ac153685..739d49acd2f 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 dbcd8d50fb8..00000000000 --- 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/mm/Makefile b/arch/x86/mm/Makefile index b7b3e4c7cfc..07dab503c9e 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/kernel/mmiotrace/kmmio.c b/arch/x86/mm/kmmio.c similarity index 100% rename from arch/x86/kernel/mmiotrace/kmmio.c rename to arch/x86/mm/kmmio.c diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/mm/mmio-mod.c similarity index 100% rename from arch/x86/kernel/mmiotrace/mmio-mod.c rename to arch/x86/mm/mmio-mod.c diff --git a/arch/x86/kernel/mmiotrace/pf_in.c b/arch/x86/mm/pf_in.c similarity index 100% rename from arch/x86/kernel/mmiotrace/pf_in.c rename to arch/x86/mm/pf_in.c diff --git a/arch/x86/kernel/mmiotrace/pf_in.h b/arch/x86/mm/pf_in.h similarity index 100% rename from arch/x86/kernel/mmiotrace/pf_in.h rename to arch/x86/mm/pf_in.h diff --git a/arch/x86/kernel/mmiotrace/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c similarity index 100% rename from arch/x86/kernel/mmiotrace/testmmiotrace.c rename to arch/x86/mm/testmmiotrace.c -- GitLab From e4b37ee68609037ffcaa2fcfae47cd31a605bb9e Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0277/2509] 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 --- arch/x86/mm/mmio-mod.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 8256546d49b..ab2bb776d31 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); -- GitLab From 736ca61fa81874b3fee205a593251b1869d0bcf1 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0278/2509] 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 --- kernel/trace/trace_mmiotrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 361472b5788..79be4a18ec1 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"); -- GitLab From c6c67c1afcce71335b18ed8769b1165c468bfb03 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0279/2509] mmiotrace: add user documentation Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- Documentation/tracers/mmiotrace.txt | 153 ++++++++++++++++++++++++++++ arch/x86/Kconfig.debug | 8 +- 2 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 Documentation/tracers/mmiotrace.txt diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt new file mode 100644 index 00000000000..84246f70387 --- /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 1d6de0d67f9..b28ace2be1a 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 -- GitLab From 0663bb6cd9a457fbd8ca95c627bb762d07321a39 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0280/2509] 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 --- arch/x86/mm/mmio-mod.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index ab2bb776d31..6d6cac84c04 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); } /* -- GitLab From 37b3619257d3190f47f233d7ed626d4b9916462c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 12 May 2008 21:20:59 +0200 Subject: [PATCH 0281/2509] 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 --- arch/x86/Kconfig.debug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index b28ace2be1a..1e53df0ba08 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. -- GitLab From 7423d1115f18627666d475fccc7c62394406ff8c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0282/2509] 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 --- arch/x86/mm/mmio-mod.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 6d6cac84c04..1f77d853203 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; -- GitLab From d0a7e8ca5b996d36219e6fc002907291c8ee677b Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0283/2509] 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 --- kernel/trace/trace_mmiotrace.c | 60 ++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 79be4a18ec1..6d2edbdde93 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, }; -- GitLab From 2039238b79b51a50f8477f53f33750e1c3fc146a Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0284/2509] mmiotrace: print overrun counts Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- kernel/trace/trace_mmiotrace.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 6d2edbdde93..d0f649a2203 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; } -- GitLab From e0fd5c2fa188311667267c02a702ae699a9fc2bd Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: [PATCH 0285/2509] mmiotrace: do not print bogus pid for maps either Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- kernel/trace/trace_mmiotrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index d0f649a2203..3c1dacdc2d8 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"); -- GitLab From 6f6f394d9ca61fcc73ecfd2f2bf58e92dc1ab269 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: [PATCH 0286/2509] doc: update mmiotrace doc to current status Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- Documentation/tracers/mmiotrace.txt | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt index 84246f70387..a4afb560a45 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: -- GitLab From 970e6fa03885f32cc43e42cb08c73a5f54cd8bd9 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: [PATCH 0287/2509] 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 --- arch/x86/mm/kmmio.c | 4 ++-- arch/x86/mm/mmio-mod.c | 7 +++---- arch/x86/mm/testmmiotrace.c | 2 +- include/linux/mmiotrace.h | 6 +----- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 3ad27b8504a..6a92d9111b6 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 1f77d853203..a8d2a0019da 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 cfa60b227c8..d877c5b423e 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 dd6b64b160f..de8e91258da 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 */ -- GitLab From 87e547fe41a8b57d6d80afc67a0031fbe477eb0d Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: [PATCH 0288/2509] 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 --- arch/x86/mm/ioremap.c | 4 +++- arch/x86/mm/kmmio.c | 13 +++++++++++-- arch/x86/mm/mmio-mod.c | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 8927c878544..a7c80a6e862 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 6a92d9111b6..93b1797666c 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 a8d2a0019da..278998c1998 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, -- GitLab From dee310d0adf41019aca476052ac3085ff286d9be Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: [PATCH 0289/2509] x86 mmiotrace: use resource_size_t for phys addresses Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- arch/x86/mm/mmio-mod.c | 11 ++++++----- include/linux/mmiotrace.h | 14 +++++++------- kernel/trace/trace_mmiotrace.c | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 278998c1998..3b04a012612 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 de8e91258da..5cbbc374e94 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 3c1dacdc2d8..b13dc19dcbb 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: -- GitLab From a50445d76c22a34ae149704ea5adaef171c8acb7 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: [PATCH 0290/2509] mmiotrace: rename kmmio_probe::user_data to :private. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- arch/x86/mm/mmio-mod.c | 4 ++-- include/linux/mmiotrace.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 3b04a012612..ed0e0e90b3e 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 5cbbc374e94..61d19e1b7a0 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? */ -- GitLab From 790e2a290b499b0400254e6870ec27969065d122 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:14 +0200 Subject: [PATCH 0291/2509] x86 mmiotrace: page level is unsigned Fixes some sparse warnings. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- arch/x86/mm/kmmio.c | 13 +++++++------ arch/x86/mm/mmio-mod.c | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 93b1797666c..b65871e6bba 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 ed0e0e90b3e..e7397e108be 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) { -- GitLab From 4d2df795f0c3eb91f97a666f47716121a2f166ed Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 15:00:46 +0200 Subject: [PATCH 0292/2509] sysprof: make it depend on X86 Signed-off-by: Thomas Gleixner --- kernel/trace/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e101c9a85f0..263e9e6bbd6 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 -- GitLab From 81d50bb254ed53a0da45a65988e4e1fa08e8a541 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 15 May 2008 19:42:49 -0700 Subject: [PATCH 0293/2509] 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 --- kernel/posix-cpu-timers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index f1525ad06cb..c42a03aef36 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); } } -- GitLab From 7f6f3a39d258adf51f0fb1fe0dab52272a1c61a4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 23:12:18 +0200 Subject: [PATCH 0294/2509] namespacecheck: fix kernel printk.c Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/printk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 8fb01c32aa3..b620e3d9613 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; -- GitLab From 42fdfa238a23643226910acf922ea930b3286032 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 23:14:51 +0200 Subject: [PATCH 0295/2509] namespacecheck: more kernel/printk.c fixes [ Stephen Rothwell : build fix ] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/kernel.h | 6 ------ kernel/printk.c | 13 ------------- 2 files changed, 19 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 792bf0aa779..f2a668c195b 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 b620e3d9613..55d16e57499 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -267,19 +267,6 @@ int log_buf_copy(char *dest, int idx, int len) return ret; } -/* - * 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: * -- GitLab From 3b8945e8d40645eecdb7d2357ca531f9b4dd9f71 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 12 May 2008 21:21:04 +0200 Subject: [PATCH 0296/2509] 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 --- kernel/printk.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 55d16e57499..8b42f87e311 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, -- GitLab From cd3a1b8562d28490b334a61d5eb05df3d722d91e Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 12 May 2008 21:21:04 +0200 Subject: [PATCH 0297/2509] 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 --- kernel/printk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 8b42f87e311..7d555615223 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; + } } } -- GitLab From ac60ad7413ca8208094609a3b88ed9b1ed012fbc Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Mon, 12 May 2008 21:21:04 +0200 Subject: [PATCH 0298/2509] 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 --- kernel/printk.c | 61 ++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 7d555615223..98ca1b76277 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; } /* -- GitLab From 091593080533a752ce66d12858d8c4105c8e1793 Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Mon, 12 May 2008 21:21:04 +0200 Subject: [PATCH 0299/2509] 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 --- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index 98ca1b76277..475fc22a285 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] == '>') { -- GitLab From 6360b1fbb4a939efd34fc770c2ebd927c55506e0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 12 May 2008 15:44:41 +0200 Subject: [PATCH 0300/2509] move BUG_TABLE into RODATA Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/avr32/kernel/vmlinux.lds.S | 2 -- arch/parisc/kernel/vmlinux.lds.S | 1 - arch/powerpc/kernel/vmlinux.lds.S | 2 -- arch/s390/kernel/vmlinux.lds.S | 1 - arch/sh/kernel/vmlinux_32.lds.S | 1 - arch/sh/kernel/vmlinux_64.lds.S | 1 - arch/x86/kernel/vmlinux_32.lds.S | 8 +++----- arch/x86/kernel/vmlinux_64.lds.S | 10 ++++------ include/asm-generic/vmlinux.lds.h | 6 ++++++ 9 files changed, 13 insertions(+), 19 deletions(-) diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S index 481cfd40c05..bc932c9b427 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 50b4a3a25d0..ff7d4ff4675 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 0c3000bf8d7..53d57d17a89 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 b4607155e8d..76c1e60c92f 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 c7113786ecd..7b4b82bd115 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 d1e177009a4..33fa4645140 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 ce5ed083a1e..aa0855471c7 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 fad3674b06a..d123747af1e 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 f054778e916..dd2cc8122ad 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) { \ -- GitLab From 962cf36c5bf6d2840b8d66ee9a606fae2f540bbd Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Thu, 15 May 2008 11:15:37 -0300 Subject: [PATCH 0301/2509] 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 --- block/blk-core.c | 2 +- include/linux/interrupt.h | 3 +-- kernel/hrtimer.c | 2 +- kernel/rcuclassic.c | 2 +- kernel/rcupreempt.c | 2 +- kernel/sched.c | 2 +- kernel/softirq.c | 7 +++---- kernel/timer.c | 2 +- net/core/dev.c | 4 ++-- 9 files changed, 12 insertions(+), 14 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 6a9cc0d22a6..75fdc65136e 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 f1fc7470d26..a86186dd047 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 421be5fe5cc..861b4088092 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 f4ffbd0f306..f6e01f3ae9c 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 e1cdf196a51..9dd827db359 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 cfa222a9153..56ea3a203a5 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 36e06174004..059256874e9 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 ceacc662657..b4da888497f 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 58296307787..cf0e16731dc 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(); -- GitLab From 668a6c3654560aef8741642478973e205a4f02bf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 19 May 2008 13:35:24 +0200 Subject: [PATCH 0302/2509] - fix mmioftrace + rcu merge interaction Signed-off-by: Thomas Gleixner --- arch/x86/mm/kmmio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index b65871e6bba..93d82038af4 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include -- GitLab From 886dd58258e6ddebe20e7aebef7b167a24bad7ee Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 15:44:38 +0200 Subject: [PATCH 0303/2509] debugging: make stacktrace independent from DEBUG_KERNEL Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- lib/Kconfig.debug | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d2099f41aa1..9c17fb9d1d5 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 -- GitLab From c6531cce6e6e4b99bcda46b6268d6f2d9e30aea4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:14 +0200 Subject: [PATCH 0304/2509] 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 --- kernel/sched.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index e2e985eeee7..6590a828138 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; } -- GitLab From 19384c0314342222b18d4c7f09cdce1ca74dfd2a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:16 -0400 Subject: [PATCH 0305/2509] 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 --- kernel/trace/trace.c | 32 +++++++++++++++++++++++--------- kernel/trace/trace_selftest.c | 1 + 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3271916ff03..0567f51bbea 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 3877dd9102f..18c5423bc97 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; -- GitLab From 4902f8849da6d2805bd291551a6dfd48f1b4f604 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:18 -0400 Subject: [PATCH 0306/2509] 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 --- kernel/trace/trace.c | 27 +++++++++++++++++++++++++-- kernel/trace/trace_sched_switch.c | 24 ------------------------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0567f51bbea..583fe24903d 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 d25ffa5eaf2..798ec0dc863 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; -- GitLab From 7e18d8e701b6798a5df11e0a16881a60ab1018b6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:19 -0400 Subject: [PATCH 0307/2509] 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 --- kernel/trace/trace_sched_wakeup.c | 67 ++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 5d2fb48e47f..bf7e91caef5 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); -- GitLab From da89a7a2536c46e76a1a4351a70a8b8417e5fed1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:20 -0400 Subject: [PATCH 0308/2509] 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 --- kernel/trace/trace_irqsoff.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 761f3ec66c5..421d6fe3650 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: -- GitLab From 41c52c0db9607e59f90da7da5309489fa06e887f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 11:46:33 -0400 Subject: [PATCH 0309/2509] 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 --- include/linux/ftrace.h | 1 + kernel/trace/ftrace.c | 170 +++++++++++++++++++++++++++++++---------- 2 files changed, 131 insertions(+), 40 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 922e23d0196..ffbbd54a720 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 89bd9a6f52e..2552454609c 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; } -- GitLab From 41bc8144d02028133bcd1d545023c6f49e8b2411 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 11:49:22 -0400 Subject: [PATCH 0310/2509] 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 --- kernel/trace/trace.c | 3 --- kernel/trace/trace.h | 4 ++-- kernel/trace/trace_functions.c | 4 ++-- kernel/trace/trace_sched_switch.c | 21 +++++++++++++++------ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 583fe24903d..0feae23d989 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 c460e85e94e..6b8bd8800d0 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 0a084656d7c..7ee7dcd76b7 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 798ec0dc863..c16935d3bc5 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; } -- GitLab From ccbfac2923c9febaeaf07a50054027a92b502718 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 14:31:07 -0400 Subject: [PATCH 0311/2509] 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 --- arch/powerpc/kernel/entry_32.S | 11 ++--------- arch/powerpc/kernel/ftrace.c | 8 +++++++- arch/powerpc/kernel/ppc_ksyms.c | 5 +++++ arch/powerpc/kernel/setup_32.c | 5 ----- arch/powerpc/kernel/setup_64.c | 5 ----- include/asm-powerpc/ftrace.h | 6 ++++++ 6 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 include/asm-powerpc/ftrace.h diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0e6221889ca..3b1dd29d9f9 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 5a4993fefa4..69ed4122346 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 cf6b5a7d8b3..4300db52662 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 22f8e2bacd3..19e8fcb9cea 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 277bf18cbbc..098fd96a394 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 00000000000..b1bfa704b6e --- /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 -- GitLab From ffdaa3582b6b39d625d585d07e329ffdc925e971 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 24 May 2008 23:45:02 +0530 Subject: [PATCH 0312/2509] 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 --- kernel/trace/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 2552454609c..9b7c54f8a62 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) -- GitLab From 492a7ea5bcf263ee02a9eb6a3ab0222a1946fade Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sun, 25 May 2008 00:10:04 +0530 Subject: [PATCH 0313/2509] 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 --- kernel/trace/ftrace.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9b7c54f8a62..1843edc098a 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++; } } -- GitLab From d031476408ae0f5196e3c579f519dfdefb099b67 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 23 May 2008 14:41:19 +0100 Subject: [PATCH 0314/2509] 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 --- kernel/hrtimer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 421be5fe5cc..493c4b8b8cb 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); } -- GitLab From 900cfa46191a7d87cf1891924cb90499287fd235 Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Thu, 22 May 2008 19:25:11 -0300 Subject: [PATCH 0315/2509] 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 --- kernel/hrtimer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 493c4b8b8cb..635739d219d 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++; -- GitLab From 62b126315369d52e40ad604e1798ff5b6265287e Mon Sep 17 00:00:00 2001 From: Chris Mennie Date: Mon, 19 May 2008 16:21:33 +0200 Subject: [PATCH 0316/2509] [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 --- sound/usb/usbquirks.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 82a8d14c26a..b7ab3ee7647 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 */ { /* -- GitLab From a72e72469a166c825196c3f20dabd352877fec2b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 01:06:55 +0300 Subject: [PATCH 0317/2509] [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 --- include/sound/uda1341.h | 2 -- sound/arm/sa11xx-uda1341.c | 2 -- sound/i2c/l3/uda1341.c | 2 -- sound/pci/au88x0/au88x0_game.c | 2 -- 4 files changed, 8 deletions(-) diff --git a/include/sound/uda1341.h b/include/sound/uda1341.h index 2e564bfb37f..110d5dc3a2b 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 0eff33ca0f7..faeddf3eced 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 bfa5d2c3608..1f4942ea141 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 bc212f41a38..e291aa59742 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: -- GitLab From 06b5fb97cec1a3ca61d10164118b00fe98a6a866 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 00:59:35 +0300 Subject: [PATCH 0318/2509] 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 --- sound/oss/msnd.c | 2 -- sound/oss/msnd.h | 2 -- sound/oss/msnd_classic.h | 2 -- sound/oss/msnd_pinnacle.c | 5 ----- sound/oss/msnd_pinnacle.h | 2 -- 5 files changed, 13 deletions(-) diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c index ba38d620009..e4282d93a1a 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 d0ca582c458..61b3955481c 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 7ffea5267f9..1a17dde2f65 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 f1f49ebf752..bf27e008f46 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 cce91148700..c18d66cbbe3 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 -- GitLab From 89fe5117928b2c1272c9376362131ded561c91ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 May 2008 16:10:37 +0200 Subject: [PATCH 0319/2509] sound: Convert to menuconfig Convert menu in sound Kconfig files to menuconfig and if. Signed-off-by: Takashi Iwai --- sound/Kconfig | 34 +++++++--------- sound/aoa/Kconfig | 11 +++--- sound/aoa/codecs/Kconfig | 4 -- sound/aoa/fabrics/Kconfig | 1 - sound/aoa/soundbus/Kconfig | 1 - sound/arm/Kconfig | 21 +++++++--- sound/core/Kconfig | 19 ++------- sound/drivers/Kconfig | 71 ++++++++++++++++----------------- sound/isa/Kconfig | 51 +++++++++--------------- sound/mips/Kconfig | 14 +++++-- sound/parisc/Kconfig | 13 ++++-- sound/pci/Kconfig | 81 +++++++------------------------------- sound/pcmcia/Kconfig | 15 ++++--- sound/ppc/Kconfig | 26 ++++++------ sound/sh/Kconfig | 16 ++++++-- sound/soc/Kconfig | 17 ++++---- sound/soc/at91/Kconfig | 2 +- sound/soc/codecs/Kconfig | 10 +---- sound/soc/davinci/Kconfig | 2 +- sound/soc/fsl/Kconfig | 2 +- sound/soc/pxa/Kconfig | 2 +- sound/soc/s3c24xx/Kconfig | 4 +- sound/soc/sh/Kconfig | 5 +-- sound/sparc/Kconfig | 17 +++++--- sound/spi/Kconfig | 13 ++++-- sound/usb/Kconfig | 16 +++++--- 26 files changed, 203 insertions(+), 265 deletions(-) diff --git a/sound/Kconfig b/sound/Kconfig index 4247406160e..a37bee094eb 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 5d5813cec4c..c081e18b954 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 d5fbd6016e9..808eb11ebac 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 50d7021ff67..3ca475a886b 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 7368b7ddfe0..839d1137b9b 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 2e4a5e0d16d..351e19ea378 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 a8d71c6c8e7..db211137578 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 159137bf4c1..79b4d3f2566 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 2639a6ab8f2..4575ba86591 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 531f8ba96a7..bb26f6cf4c0 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 a5a7f9d75d0..9b61d95010f 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 d95fbb2b5b9..b148c0b3ef3 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 c9fa1a2bc58..7fbb190adf6 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 cacb0b13688..777de2b1717 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 b7e08ef22a9..cfc14398580 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 18f28ac4bfe..fd7bc4f8907 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 5cb93fd3a40..905186502e0 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 3903ab7dfa4..d4a5fe42f6e 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 20680c551aa..8f7e3383490 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 257101f44e9..19802e27df4 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 484f883459e..18a40dc8ad9 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 1f6dbfc4caa..b9f2353effe 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 4c1e013381c..54bd604012a 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 079e22af074..d75deba5617 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 0d08c29213c..e6485be2e6f 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 9351b8a765b..ffcdc8f4ef6 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 -- GitLab From 6938d6b2a90d5e2ffaef037852652a1333502519 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 May 2008 16:11:26 +0200 Subject: [PATCH 0320/2509] [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 --- sound/drivers/Kconfig | 21 +++++++++++++++++++++ sound/pci/Kconfig | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 79b4d3f2566..255fd18b9ae 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 b148c0b3ef3..8fe5dac3942 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 -- GitLab From 62cf872a8eec1f11aacbec0ac3fe3698bfa9b403 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 May 2008 12:15:15 +0200 Subject: [PATCH 0321/2509] [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 --- .../sound/alsa/ALSA-Configuration.txt | 2 +- .../alsa/DocBook/writing-an-alsa-driver.tmpl | 4 ++-- include/sound/core.h | 8 ++++---- sound/core/Kconfig | 10 ++++++---- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_hwdep.c | 2 +- sound/pci/pcxhr/pcxhr.c | 4 ++-- sound/pci/pcxhr/pcxhr_core.c | 18 +++++++++--------- 8 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 0bbee38acd2..e59569462cb 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 b03df4d4795..e13c4e67029 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 695ee53488a..558b96284bd 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 db211137578..335d45ecde6 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 a6be6e3e871..d2e1093f8e9 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 2177d9af533..6e18a422d99 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 7fdcdc8c6b6..2c7e2533679 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 78aa81feaa4..abe5c59b72d 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 -- GitLab From 142054a389ebf7972b4eee822ad7c55ff852b649 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 26 May 2008 12:59:16 +0300 Subject: [PATCH 0322/2509] [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 --- sound/soc/pxa/Kconfig | 9 ++++ sound/soc/pxa/Makefile | 3 +- sound/soc/pxa/em-x270.c | 102 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 sound/soc/pxa/em-x270.c diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 18a40dc8ad9..12f6ac99b04 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 04e5646f75b..5bc8edf9dca 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 00000000000..02dcac39cdf --- /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"); -- GitLab From f269002e61446ed3410d8ca5f06ebca1e2760cb5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:44:55 +0200 Subject: [PATCH 0323/2509] [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 --- sound/pci/hda/hda_intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6ba7ac01d9f..7f62196989a 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); -- GitLab From abbc9d1b25637b1948a4718fa8f7b257233136bc Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:48:01 +0200 Subject: [PATCH 0324/2509] [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 --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7f62196989a..6e2dc4f5ca7 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 }, -- GitLab From 6dda9f4a95905f2b38e79e3737da5e25397e6acb Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:05:31 +0200 Subject: [PATCH 0325/2509] [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 --- .../sound/alsa/ALSA-Configuration.txt | 6 +- sound/pci/hda/patch_realtek.c | 289 +++++++++++++++++- 2 files changed, 291 insertions(+), 4 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index e59569462cb..f48939e97ab 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 b0a2a262ece..c659588e26d 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 }, -- GitLab From 531240ff520406c793a110e1c0f187d931f47d66 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:10:25 +0200 Subject: [PATCH 0326/2509] [ALSA] hda - Fix vref pincap check in alc882 auto-detection Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c659588e26d..8174050da15 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; } -- GitLab From 2f8932863d243a744ccd3dc005490ad9d2eae478 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:14:47 +0200 Subject: [PATCH 0327/2509] [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 --- sound/pci/hda/patch_realtek.c | 47 +++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8174050da15..5770b9c3efa 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; -- GitLab From f9423e7a94eb2dfef3503dde76d17eaf342ab962 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:32:25 +0200 Subject: [PATCH 0328/2509] [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 --- sound/pci/hda/patch_realtek.c | 37 +++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5770b9c3efa..cb3e0283f0c 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"; -- GitLab From b1829d2705daa7cb72eb1e08bdc8b7e9fad34266 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 28 May 2008 01:22:08 +0200 Subject: [PATCH 0329/2509] ftrace: fix merge Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ffbbd54a720..b482fe88bc0 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 -- GitLab From a93bbaa77ea61c6bad684263a65f812b31bf9791 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 27 May 2008 17:59:24 +0200 Subject: [PATCH 0330/2509] [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 --- .../sound/alsa/ALSA-Configuration.txt | 4 ++ sound/core/init.c | 67 +++++++++++-------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index f48939e97ab..529073dea19 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 ac057341613..5c254d498ae 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; -- GitLab From 3c65e8743bf8b5cf0f90e8d767bf1d8b50c14c76 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 28 May 2008 08:58:56 -0500 Subject: [PATCH 0331/2509] 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 --- fs/jfs/jfs_imap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 734ec916bea..d6363d8309d 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 -- GitLab From e13ac2e9b18bde51cf32c69c2209df25791ab3e5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 May 2008 17:58:05 +0100 Subject: [PATCH 0332/2509] [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 --- include/sound/soc.h | 15 +++++++++ sound/soc/soc-core.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index bca9538d9e5..9fa2093e74e 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 a3f091e0843..f594ab888e1 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); -- GitLab From b7482f52789266e2548be5d0f6420c9fc12428d8 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 28 May 2008 17:58:06 +0100 Subject: [PATCH 0333/2509] [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 --- sound/soc/codecs/Kconfig | 3 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/uda1380.c | 852 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/uda1380.h | 89 ++++ 4 files changed, 946 insertions(+) create mode 100644 sound/soc/codecs/uda1380.c create mode 100644 sound/soc/codecs/uda1380.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index d4a5fe42f6e..7beefccfa82 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 4e1314c9d3e..d5926a11707 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 00000000000..cb50486201f --- /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 00000000000..f9d885c8bf0 --- /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 */ -- GitLab From b786af117b360843349cf66165c4efa0217ca2a7 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Wed, 7 May 2008 04:29:17 +1000 Subject: [PATCH 0334/2509] [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 --- arch/powerpc/sysdev/dcr.c | 154 +++++++++++++++++++++++------- include/asm-powerpc/dcr-generic.h | 49 ++++++++++ include/asm-powerpc/dcr-mmio.h | 20 ++-- include/asm-powerpc/dcr-native.h | 16 ++-- include/asm-powerpc/dcr.h | 39 +++++++- 5 files changed, 231 insertions(+), 47 deletions(-) create mode 100644 include/asm-powerpc/dcr-generic.h diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 437e48d3ae3..5f39a79b066 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 00000000000..35b71599ec4 --- /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 08532ff1899..acd491dbd45 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 f8398ce8037..72d2b72c739 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 9338d50538f..53b283050ab 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 */ -- GitLab From 71f349799b34c8b6ce3df42126b4de6cfa16456d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 15 May 2008 16:46:39 +1000 Subject: [PATCH 0335/2509] [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 --- arch/powerpc/boot/dts/bamboo.dts | 142 +++++++------- arch/powerpc/boot/dts/canyonlands.dts | 222 +++++++++++----------- arch/powerpc/boot/dts/ebony.dts | 164 ++++++++-------- arch/powerpc/boot/dts/ep405.dts | 100 +++++----- arch/powerpc/boot/dts/glacier.dts | 262 +++++++++++++------------- arch/powerpc/boot/dts/haleakala.dts | 136 ++++++------- arch/powerpc/boot/dts/holly.dts | 122 ++++++------ arch/powerpc/boot/dts/katmai.dts | 210 +++++++++++---------- arch/powerpc/boot/dts/kilauea.dts | 182 +++++++++--------- arch/powerpc/boot/dts/makalu.dts | 182 +++++++++--------- arch/powerpc/boot/dts/ps3.dts | 16 +- arch/powerpc/boot/dts/rainier.dts | 162 ++++++++-------- arch/powerpc/boot/dts/sequoia.dts | 172 ++++++++--------- arch/powerpc/boot/dts/taishan.dts | 212 ++++++++++----------- arch/powerpc/boot/dts/walnut.dts | 118 ++++++------ arch/powerpc/boot/dts/warp.dts | 106 ++++++----- arch/powerpc/boot/dts/yosemite.dts | 146 +++++++------- 17 files changed, 1344 insertions(+), 1310 deletions(-) diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts index ba2521bdaab..6ce0cc2c020 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 39634124929..f9fe0325215 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 5079dc890e0..ec2d142291b 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 92938557ac8..53ef06cc213 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 0f2fc077d8d..463650c5f61 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 b5d95ac24db..2c2fceaabbc 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 b5d87895fe0..f87fe7b9ced 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 cc2873a531d..b94bf61b9bc 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 48c9a6e71f1..3ed6a8fee1d 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 84cc5e72ddd..1dfcd7ed199 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 379ded282d5..96ba5b512af 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 6a8fa7089ea..2cd87f66f81 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 72d67564bdf..149dabc5521 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 e808e1c5593..dcb749884b6 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 a328607c8f8..4a9f726ada1 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 b04a52e22bf..c52e4fb89ab 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 0d6d332814e..e39422aa0d8 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 >; }; }; -- GitLab From 6f031101f5c6bb44762911909da575127f676eb8 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Fri, 16 May 2008 00:41:23 +1000 Subject: [PATCH 0336/2509] [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 --- arch/powerpc/boot/dts/rainier.dts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index 2cd87f66f81..2afb63a42ea 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>; -- GitLab From 0393cb615f369b6ea0e636dd4d1e25675657dc75 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 29 Apr 2008 13:27:46 +1000 Subject: [PATCH 0337/2509] [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 --- arch/powerpc/boot/dts/warp.dts | 55 +++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index c52e4fb89ab..340018cf16b 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 { -- GitLab From 4ebef31fa6e013e5cd3d4522e6018eb6d55046be Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 20 May 2008 08:28:52 -0500 Subject: [PATCH 0338/2509] [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 --- arch/powerpc/boot/cuboot-warp.c | 47 +++- arch/powerpc/platforms/44x/warp-nand.c | 49 ++++- arch/powerpc/platforms/44x/warp.c | 293 ++++++++++++++++++++----- 3 files changed, 324 insertions(+), 65 deletions(-) diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index eb108a87749..21780210057 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 9150318cfc5..d293c702e73 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 39cf6150a72..9565995cba7 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); -- GitLab From 0723abd0b2c9d4603b8c51d6615800c2439a328e Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 20 May 2008 07:59:23 -0500 Subject: [PATCH 0339/2509] [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 --- arch/powerpc/sysdev/dcr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 5f39a79b066..a8ba9983dd5 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) -- GitLab From c18f68e4d809a517ed8df540bac2993a4f14d9a4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 29 May 2008 18:53:05 +0200 Subject: [PATCH 0340/2509] [ALSA] Clean up sound/pci/ac97/Makefile Signed-off-by: Takashi Iwai --- sound/pci/ac97/Makefile | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 0be48b1a22d..ae36950f256 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)) -- GitLab From 23ce1547638443f0053dd674e728062c48ff0e39 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:22:22 +0200 Subject: [PATCH 0341/2509] [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 --- sound/pci/Makefile | 2 +- sound/pci/ac97/Makefile | 3 --- sound/pci/{ac97 => }/ak4531_codec.c | 32 ++++++----------------------- 3 files changed, 7 insertions(+), 30 deletions(-) rename sound/pci/{ac97 => }/ak4531_codec.c (96%) diff --git a/sound/pci/Makefile b/sound/pci/Makefile index 85ef14bc805..65b25d221cd 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 ae36950f256..41fa322f097 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/ak4531_codec.c similarity index 96% rename from sound/pci/ac97/ak4531_codec.c rename to sound/pci/ak4531_codec.c index c0c1633999e..6a99eed2d8b 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ak4531_codec.c @@ -270,7 +270,7 @@ 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[] = { +static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = { AK4531_DOUBLE_TLV("Master Playback Switch", 0, AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1, @@ -379,8 +379,9 @@ static u8 snd_ak4531_initial_map[0x19 + 1] = { 0x01 /* 19: Mic Amp Setup */ }; -int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, - struct snd_ak4531 **rak4531) +int __devinit snd_ak4531_mixer(struct snd_card *card, + struct snd_ak4531 *_ak4531, + struct snd_ak4531 **rak4531) { unsigned int idx; int err; @@ -476,7 +477,8 @@ static void snd_ak4531_proc_read(struct snd_info_entry *entry, ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB"); } -static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531) +static void __devinit +snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531) { struct snd_info_entry *entry; @@ -484,25 +486,3 @@ static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak453 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) -- GitLab From 8bb8b453cb458d8f62411e78a4cfd6d860b503b6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:47:45 +0200 Subject: [PATCH 0342/2509] [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 --- sound/pci/trident/trident_memory.c | 178 ----------------------------- 1 file changed, 178 deletions(-) diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index df9b487fa17..3fd7f1b29b0 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); -- GitLab 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: [PATCH 0343/2509] 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 --- arch/arm/kernel/atags.c | 7 +++---- include/asm-arm/kexec.h | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c index 64c420805e6..56fef9a0550 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 47fe34d692d..c8986bb99ed 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 -- GitLab 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: [PATCH 0344/2509] 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 --- arch/arm/kernel/atags.c | 80 ++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c index 56fef9a0550..42a1a1415fa 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); -- GitLab 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: [PATCH 0345/2509] 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 --- include/asm-arm/arch-ns9xxx/hardware.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h index 0b7b34603f1..0dca11ce21f 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 -- GitLab From 72860b0f3c4a303498c9e16c8a4a38ddf23d56de Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 11:25:03 +0200 Subject: [PATCH 0346/2509] 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 --- sound/oss/Kconfig | 49 ++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 3be2dc1025b..33940139844 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" -- GitLab From 2621f0338ce4e3e57cc32a967f5a3d2999390fe3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 11:27:24 +0200 Subject: [PATCH 0347/2509] [ALSA] trivial clean up of sound/isa/sb/Makefile Remove unneeded sort in sound/isa/sb/Makefile. Signed-off-by: Takashi Iwai --- sound/isa/sb/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index c9d1c986d70..1098a56b2f4 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)) -- GitLab From a5003fc04113c217370409beac812831cbf6e0ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:49:41 +0200 Subject: [PATCH 0348/2509] [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 --- sound/pci/emu10k1/memory.c | 66 ++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 916c1dbcd53..128eaca17a6 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; } -- GitLab From 7a14ce1d8c1d3a6118d406e64eaf9aa70375e085 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 15:43:53 +0200 Subject: [PATCH 0349/2509] nohz: reduce jiffies polling overhead Signed-off-by: Ingo Molnar --- kernel/time/tick-sched.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index b854a895591..cb75394ed00 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); -- GitLab From 014c257cce65e9d1cd2d28ec1c89a37c536b151d Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 31 May 2008 14:23:50 +0530 Subject: [PATCH 0350/2509] 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 --- arch/arm/Kconfig | 2 + arch/arm/boot/compressed/Makefile | 6 ++ arch/arm/kernel/Makefile | 5 ++ arch/arm/kernel/armksyms.c | 5 ++ arch/arm/kernel/entry-common.S | 47 +++++++++++ arch/arm/kernel/ftrace.c | 128 ++++++++++++++++++++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 arch/arm/kernel/ftrace.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..3845e5c8a34 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 de9d9ee5095..95baac4939e 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 ad455ff5aeb..eb9092ca800 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 688b7b1ee41..3b132215cbf 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 597ed00a08d..8f79a4789ed 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 00000000000..f4cb4cc3fa0 --- /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; +} -- GitLab From d2cd74b158d7214a556226e3312f9fb1de64d7ae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 2 Jun 2008 11:45:53 +0200 Subject: [PATCH 0351/2509] [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 --- include/sound/emu10k1.h | 1 + sound/pci/emu10k1/emu10k1_main.c | 1 + sound/pci/emu10k1/emumixer.c | 13 ++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 7b7b9b13b4d..10ee28eac01 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 548c9cc81af..2f283ea6ad9 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 fd221209abc..f34bbfb705f 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; -- GitLab From 76094a2cf46e4ab776055d4086615b884408568c Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Wed, 28 May 2008 00:03:18 +0530 Subject: [PATCH 0352/2509] 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 --- kernel/trace/trace.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0feae23d989..12f5e817380 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; } -- GitLab From ad90c0e3ce8d20d6873b57e36181ef6d7a0097fe Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 27 May 2008 20:48:37 -0400 Subject: [PATCH 0353/2509] 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 --- include/linux/ftrace.h | 6 ++ kernel/trace/ftrace.c | 157 +++++++++++++++++++++++++++++------------ 2 files changed, 116 insertions(+), 47 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b482fe88bc0..623819433ed 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 1843edc098a..f762f5a2d33 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; } -- GitLab From e0773410247f1e5fc6f7c52a4c5f3c6c9873d527 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 31 May 2008 14:24:02 +0530 Subject: [PATCH 0354/2509] 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 --- arch/arm/kernel/kprobes.c | 2 +- include/asm-arm/kprobes.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 5593dd20721..5ee39e10c8d 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 c042194d3ab..b1a37876942 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); -- GitLab From 1a7e612fa5ea0311232bd5418a40ec7280557789 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:18:11 +0100 Subject: [PATCH 0355/2509] [ARM] 5074/1: fix warning: missing terminating ' character Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa27x-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h index 9cf0b1f8811..2d4e9cd3a5e 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 */ -- GitLab From 720046de27ec2a96d4497dbca8ee98657efa059c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:13:36 +0100 Subject: [PATCH 0356/2509] [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 --- arch/arm/mach-pxa/lpd270.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a20e4b1649d..6fd7b8b753f 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; } -- GitLab From 04ba0f656f7580d8a51a5b3441e088309141b67a Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:23:25 +0100 Subject: [PATCH 0357/2509] [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 --- drivers/pcmcia/pxa2xx_cm_x270.c | 4 ++++ drivers/pcmcia/pxa2xx_mainstone.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index e7ab060ff11..4a6c020afb3 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 145b85e0f02..36a59960b5a 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; -- GitLab From 4e5e8de0dbdeb08df2b4c15fa2b0ba2216091793 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:28:11 +0100 Subject: [PATCH 0358/2509] [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 --- drivers/pcmcia/pxa2xx_cm_x270.c | 11 +++++++---- drivers/pcmcia/pxa2xx_mainstone.c | 9 +++++---- drivers/pcmcia/pxa2xx_sharpsl.c | 12 +++++++----- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 4a6c020afb3..f123fce65f2 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 36a59960b5a..92d1cc33808 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 d5c33bd78d6..d71f93d4583 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); -- GitLab From ffdf786291636137ef2d51c3a5d340793032aa28 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 14:57:59 +0100 Subject: [PATCH 0359/2509] [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 --- arch/arm/mach-pxa/standby.S | 82 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index 167412e6bec..a37ef1c4b9e 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) -- GitLab From e3ba22db09408baee721897fb1b50e16f071d916 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Sat, 24 May 2008 17:06:45 +0100 Subject: [PATCH 0360/2509] [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 --- arch/arm/mach-at91/Kconfig | 6 + arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/board-yl-9200.c | 853 +++++++++++++---------------- 3 files changed, 394 insertions(+), 466 deletions(-) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 0fc07b6db74..3d549a9afe1 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 8d9bc0153b1..995be14b2c4 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 b5717108991..7079050ab88 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: -- GitLab From 1d46e379aae7349069f459618f53fd5193c2fd29 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 4 Jul 2008 00:59:37 -0600 Subject: [PATCH 1162/2509] 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 --- arch/powerpc/boot/wrapper | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 592a6ea474f..644bf9d4ea0 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 -- GitLab From 823ed72e8fe566983b121e8cc3147dd50ce63a8a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 09:28:32 +0200 Subject: [PATCH 1163/2509] block: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/aoe/aoecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 41f818be2f7..2f1746295d0 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"); -- GitLab From 72f6befeea7dc634a83219287d5b874734b85637 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Fri, 4 Jul 2008 09:33:03 +0200 Subject: [PATCH 1164/2509] avr32: Fix typo of IFSR in a comment in the PIO header file Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/pio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h index 7795116a483..9484dfcc08f 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 */ -- GitLab From be1fd70fea1100c57f3aa1934ebb93abc474e50c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:51:21 +0200 Subject: [PATCH 1165/2509] 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 --- drivers/block/paride/pt.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 8b9549ab4a4..27455ee1e9d 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; } } -- GitLab From 5b6155ee70e9c4d2ad7e6f514c8eee06e2711c3a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:29:16 +0200 Subject: [PATCH 1166/2509] 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 --- drivers/block/pktcdvd.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 589850cff35..85e44d07eab 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, }; -- GitLab From 2610324fcacf38a24b630090ebcb802538763187 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:29:31 +0200 Subject: [PATCH 1167/2509] DAC960: push down BKL Signed-off-by: Alan Cox Cc: Richard Knutsson Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/DAC960.c | 157 ++++++++++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 56 deletions(-) diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index cd03473f354..a002a381df9 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 = { -- GitLab From 27f8221af406e43b529a5425bc99c9b1e9bdf521 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:30:03 +0200 Subject: [PATCH 1168/2509] 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 --- block/blk-settings.c | 24 ++++++++++++++++++++---- drivers/ata/libata-scsi.c | 3 ++- include/linux/blkdev.h | 1 + 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/block/blk-settings.c b/block/blk-settings.c index 8dd86418f35..dfc77012843 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) { @@ -314,6 +313,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 diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a43649a46..499ccc628d8 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 e04c4ac8a7c..1ffd8bfdc4c 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); -- GitLab From 30c00eda73d5db5bd64dd0c370161abd8df5ba4a Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:31:11 +0200 Subject: [PATCH 1169/2509] 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 --- block/blk-map.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/block/blk-map.c b/block/blk-map.c index 813011ef827..ddd96fb11a7 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 -- GitLab From 62858dacc8dea55c5bdb474ccd8acb0657e23dd0 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:31:50 +0200 Subject: [PATCH 1170/2509] 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 --- drivers/scsi/sr.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c82df8bd4d8..27f5bfd1def 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) -- GitLab From fce5384755e8e0e56c5609d2972db4702990d592 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:33:01 +0200 Subject: [PATCH 1171/2509] 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 --- drivers/cdrom/cdrom.c | 274 ++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 181 deletions(-) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 69f26eb6415..a5da3563265 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; } /* -- GitLab From 7c0c0b5b19611ac15eec69043cb5588f6cbfbd7b Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Fri, 4 Jul 2008 09:33:17 +0200 Subject: [PATCH 1172/2509] 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 --- drivers/block/pktcdvd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 85e44d07eab..45bee918c46 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; -- GitLab From 8b3d3567f72aa61d5d6f4ce89d289b154e1ea866 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Fri, 4 Jul 2008 09:33:33 +0200 Subject: [PATCH 1173/2509] ramfs: enable splice write Signed-off-by: Octavian Purdila Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- fs/ramfs/file-mmu.c | 1 + fs/ramfs/file-nommu.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 9590b902430..78f613cb9c7 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 0989bc2c2f6..52312ec93ff 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, }; -- GitLab From 32502b8413a77b54b9e19809404109590c32dfb7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 4 Jul 2008 09:35:17 +0200 Subject: [PATCH 1174/2509] 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 --- fs/splice.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index aa5f6f60b30..399442179d8 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 -- GitLab From ba8dd03ac09f51a69c154b8cb508b701d713a2cd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 4 Jul 2008 11:26:40 +0200 Subject: [PATCH 1175/2509] 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 --- include/linux/smp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/smp.h b/include/linux/smp.h index 55261101d09..48262f86c96 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -8,7 +8,6 @@ #include #include -#include #include extern void cpu_idle(void); -- GitLab From c4acb2c0669c5c5c9b28e9d02a34b5c67edf7092 Mon Sep 17 00:00:00 2001 From: Gregory Haskins Date: Fri, 27 Jun 2008 14:29:55 -0600 Subject: [PATCH 1176/2509] 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 --- kernel/sched.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 677c80b9a6b..d99aeabeb72 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; -- GitLab From 2087a1ad822cd3a68b73338457047fcc54da726b Mon Sep 17 00:00:00 2001 From: Gregory Haskins Date: Fri, 27 Jun 2008 14:30:00 -0600 Subject: [PATCH 1177/2509] 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 --- kernel/sched.c | 14 ++++++++++++++ kernel/sched_fair.c | 21 ++------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index d99aeabeb72..bbc40c3a065 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 2e43d4a748c..f2aa987027d 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; -- GitLab From 46ac22bab42cc868b9c1d0e915ddbc8e8065a44d Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Tue, 1 Jul 2008 14:30:06 +0530 Subject: [PATCH 1178/2509] 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 --- kernel/sched.c | 1 + kernel/sched_stats.h | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index bbc40c3a065..996bc15196a 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 80179ef7450..8385d43987e 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 */ -- GitLab From 5b2d281acb04a29fcdc76ced5ca6099565a0747f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 27 Jun 2008 14:43:20 -0700 Subject: [PATCH 1179/2509] 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 --- drivers/infiniband/core/uverbs_main.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 8ede1e475ce..fdfcf7910d9 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; } -- GitLab From 63dd10846d4917534e9ec7bddf43be786effe8b8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:43 +0200 Subject: [PATCH 1180/2509] 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 --- arch/arm/mach-mx3/mx31ads.c | 1 + include/asm-arm/arch-mxc/hardware.h | 32 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 7e89bdc23a9..5addbb7f711 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 e87ff0679d5..4ed2d8072d0 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__ */ -- GitLab From 036bb15ec94216e28cb1550af0fdcdfb90c549df Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:44 +0200 Subject: [PATCH 1181/2509] 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 --- drivers/serial/imx.c | 50 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 5a375bf0ebf..6226e66c796 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(); } } -- GitLab From 2582d8c1655f2eda42d5358a242b256fd6e88571 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:45 +0200 Subject: [PATCH 1182/2509] 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 --- drivers/serial/imx.c | 28 +++++++++++++++++++--------- include/asm-arm/arch-imx/imx-uart.h | 2 ++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 6226e66c796..77968432b81 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 3a685e1780e..d54eb1d4802 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; }; -- GitLab From dbff4e9ea2e83fda89143389bfb229cb29425a32 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:45 +0200 Subject: [PATCH 1183/2509] 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 --- arch/arm/mach-imx/mx1ads.c | 10 +++ drivers/serial/imx.c | 129 ++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index a9778c1587a..9635d5812bc 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 77968432b81..8d6cb745bd9 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; -- GitLab From 38a41fdf94c449c165213e4665c3f8a0d30f8aba Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:46 +0200 Subject: [PATCH 1184/2509] 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 --- arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clock.c | 205 ++++++++++++++++++++++++++++ arch/arm/mach-imx/cpufreq.c | 20 ++- arch/arm/mach-imx/generic.c | 76 ----------- arch/arm/mach-imx/time.c | 23 +++- drivers/mmc/host/imxmmc.c | 19 ++- drivers/serial/imx.c | 25 +++- drivers/spi/spi_imx.c | 38 ++++-- include/asm-arm/arch-imx/hardware.h | 8 -- 9 files changed, 307 insertions(+), 109 deletions(-) create mode 100644 arch/arm/mach-imx/clock.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 88d5e61a2e1..b047c7e795a 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 00000000000..6a90fe5578d --- /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 e548ba74a4d..be0809b33e0 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 4cfc9d3af28..98ddd8a6d05 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 d86d124aea2..5a41e96e858 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 95f33e87a99..ef2f6fc8654 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 8d6cb745bd9..9e2162ebf1b 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 c730d05bfeb..bd0729b6b6e 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 adffb6acf42..6542ca5e8c3 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 -- GitLab From c0db2ea4e366c94dd3f880928c02534156e3d1b9 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:47 +0200 Subject: [PATCH 1185/2509] 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 --- arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/clock.c | 331 +++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/clock.h | 67 +++++++ 3 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-mxc/clock.c create mode 100644 include/asm-arm/arch-mxc/clock.h diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index f96dc036206..3eb181cb7af 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 00000000000..1aa86fd60d7 --- /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 00000000000..24caa2b7c91 --- /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__ */ -- GitLab From df1bf4bdb2a3a26d4bde8ae1aefc16385dd4898f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: [PATCH 1186/2509] i.MX3: introduce clock API This patch introduces the clock API for for arch-mxc Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/clock.c | 1147 +++++++++++++++++++++++++++++ arch/arm/mach-mx3/crm_regs.h | 401 ++++++++++ include/asm-arm/arch-mxc/common.h | 1 + 4 files changed, 1550 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mx3/clock.c create mode 100644 arch/arm/mach-mx3/crm_regs.h diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index cbec997f332..febb37f2393 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 00000000000..2f3635943e7 --- /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 00000000000..4a0e0ede23b --- /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 23b4350edbd..c6d4aa36063 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 -- GitLab From e3d13ff4b9d3b05d7a969153e2c049548e25deea Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: [PATCH 1187/2509] 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 --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/devices.c | 153 ++++++++++++++++++++++++++++ drivers/serial/Kconfig | 2 +- drivers/serial/imx.c | 100 ++++++++++++++---- include/asm-arm/arch-mxc/imx-uart.h | 32 ++++++ 5 files changed, 267 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mach-mx3/devices.c create mode 100644 include/asm-arm/arch-mxc/imx-uart.h diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index febb37f2393..a788cb0b793 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 00000000000..1bc6d23a1d5 --- /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 9bc42763623..0843c540068 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 9e2162ebf1b..549440b098b 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 00000000000..83fb72c4048 --- /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 -- GitLab From 07bd1a6cc7cbb3f373fbe49b204c6cde5e9155fc Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:49 +0200 Subject: [PATCH 1188/2509] 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 --- arch/arm/Kconfig | 2 + arch/arm/mach-mx3/devices.c | 27 ++++ arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/gpio.c | 253 ++++++++++++++++++++++++++++++ arch/arm/plat-mxc/irq.c | 3 + include/asm-arm/arch-mxc/common.h | 1 + include/asm-arm/arch-mxc/gpio.h | 42 +++++ include/asm-arm/arch-mxc/mx31.h | 19 +++ 8 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-mxc/gpio.c create mode 100644 include/asm-arm/arch-mxc/gpio.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..5c8c1a89be7 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 1bc6d23a1d5..5c0320fce5b 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 3eb181cb7af..66272a6fc32 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 00000000000..4a7736717d8 --- /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 2ad5a6917b3..88f0cfababd 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 c6d4aa36063..8774783ed98 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 00000000000..d393e15f5a6 --- /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 36a1af495bb..98e6a4cd1ea 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 */ -- GitLab From 90292ea60f1c730efb9fea02b2e12676da89ebef Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: [PATCH 1189/2509] MXC: add io multiplexing functions for mx3 This patch adds functions to use the io multiplexer on mx3 platforms. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/iomux.c | 111 ++++++ include/asm-arm/arch-mxc/iomux-mx3.h | 501 +++++++++++++++++++++++++++ 3 files changed, 613 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mx3/iomux.c create mode 100644 include/asm-arm/arch-mxc/iomux-mx3.h diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index a788cb0b793..68f062b70d3 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 00000000000..adc51feefc1 --- /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 00000000000..7509e7692f0 --- /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 + -- GitLab From d0f349fbce2905607e0473d2358f97f48866e52c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: [PATCH 1190/2509] 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 --- arch/arm/Kconfig | 2 + arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/mx31ads.c | 13 +- arch/arm/mach-mx3/time.c | 148 ----------------- arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/time.c | 228 +++++++++++++++++++++++++++ include/asm-arm/arch-mxc/common.h | 4 +- include/asm-arm/arch-mxc/mxc.h | 112 ++----------- include/asm-arm/arch-mxc/mxc_timer.h | 158 +++++++++++++++++++ 9 files changed, 418 insertions(+), 251 deletions(-) delete mode 100644 arch/arm/mach-mx3/time.c create mode 100644 arch/arm/plat-mxc/time.c create mode 100644 include/asm-arm/arch-mxc/mxc_timer.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c8c1a89be7..8a9a84c4adf 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 68f062b70d3..562c75d2e37 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 5addbb7f711..eba3e0cd428 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 fb565c98dbf..00000000000 --- 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 66272a6fc32..e3cc25c6d46 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 00000000000..3bf86343fdf --- /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 8774783ed98..a6d2e24aab1 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 146d3f60951..1df4e2f2492 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__ @@ -20,97 +29,6 @@ # define cpu_is_mx31() (0) #endif -/* - ***************************************** - * 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 00000000000..6cb11f4f1a0 --- /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 -- GitLab From 4bc256501a159abc7e9fee43f63c68894f6a11d8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:51 +0200 Subject: [PATCH 1191/2509] 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 --- include/asm-arm/arch-mxc/board-mx31ads.h | 5 ++++ include/asm-arm/arch-mxc/debug-macro.S | 38 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 include/asm-arm/arch-mxc/debug-macro.S diff --git a/include/asm-arm/arch-mxc/board-mx31ads.h b/include/asm-arm/arch-mxc/board-mx31ads.h index 8590127760a..1bc6fb0f9a8 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 00000000000..34befbb2ea4 --- /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 -- GitLab From 1b53218bfa4c0e17fc16ff7fadb85b82bbd3c77c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:51 +0200 Subject: [PATCH 1192/2509] 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 --- arch/arm/configs/mx31ads_defconfig | 839 +++++++++++++++++++++++++++++ 1 file changed, 839 insertions(+) create mode 100644 arch/arm/configs/mx31ads_defconfig diff --git a/arch/arm/configs/mx31ads_defconfig b/arch/arm/configs/mx31ads_defconfig new file mode 100644 index 00000000000..e05271753e1 --- /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 -- GitLab From ce8ffef0bfd6e55d5da3923d8e9af27c3b5c4eff Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:52 +0200 Subject: [PATCH 1193/2509] MX31: add basic pcm037 board support This patch adds basic board support for phytecs pmc037 board. Signed-off-by: Sascha Hauer --- arch/arm/configs/pcm037_defconfig | 748 ++++++++++++++++++++++++ arch/arm/mach-mx3/Kconfig | 6 + arch/arm/mach-mx3/Makefile | 1 + arch/arm/mach-mx3/pcm037.c | 130 ++++ include/asm-arm/arch-mxc/board-pcm037.h | 27 + include/asm-arm/arch-mxc/debug-macro.S | 3 + 6 files changed, 915 insertions(+) create mode 100644 arch/arm/configs/pcm037_defconfig create mode 100644 arch/arm/mach-mx3/pcm037.c create mode 100644 include/asm-arm/arch-mxc/board-pcm037.h diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig new file mode 100644 index 00000000000..62747458647 --- /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 5fe8606cac0..8b7b49a9292 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 562c75d2e37..b09ca608349 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 00000000000..a34ae6de266 --- /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 00000000000..82232ba3c8f --- /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 34befbb2ea4..81caa0aacfe 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -15,6 +15,9 @@ #ifdef CONFIG_MACH_MX31ADS #include +#endif +#ifdef CONFIG_MACH_PCM037 +#include #endif .macro addruart,rx -- GitLab From 9a4cd7a5c836e189a1712c9ffd2d76b2302ce212 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 5 Jul 2008 10:02:53 +0200 Subject: [PATCH 1194/2509] 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(+) --- 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(+) create mode 100644 arch/arm/configs/mx31litekit_defconfig create mode 100644 arch/arm/mach-mx3/mx31lite.c create mode 100644 include/asm-arm/arch-mxc/board-mx31lite.h diff --git a/arch/arm/configs/mx31litekit_defconfig b/arch/arm/configs/mx31litekit_defconfig new file mode 100644 index 00000000000..4f41c413568 --- /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 8b7b49a9292..db9431dee1b 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 b09ca608349..8b21abb71fb 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 00000000000..ea23a8ec685 --- /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 00000000000..e4e5cf5ad7d --- /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 81caa0aacfe..5add48b6665 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -18,6 +18,9 @@ #endif #ifdef CONFIG_MACH_PCM037 #include +#endif +#ifdef CONFIG_MACH_MX31LITE +#include #endif .macro addruart,rx -- GitLab From 9e8a30dce1bd38cf7b941c707da504d28a907f5c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:53 +0200 Subject: [PATCH 1195/2509] 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 --- arch/arm/mach-mx3/mx31lite.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index ea23a8ec685..1372c1a1fc3 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 -- GitLab From 259bcaae9a2f28d7e3303b202b64a1fb0a9ab9e4 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:54 +0200 Subject: [PATCH 1196/2509] 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 --- arch/arm/plat-mxc/irq.c | 67 +++++++++++++++++++++++++-------- include/asm-arm/arch-mxc/irqs.h | 13 ------- include/asm-arm/arch-mxc/mx31.h | 2 + include/asm-arm/arch-mxc/mxc.h | 38 ------------------- 4 files changed, 53 insertions(+), 67 deletions(-) diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 88f0cfababd..1fbe01da692 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 b2c5205e196..f416130718c 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 98e6a4cd1ea..a7373e4a56c 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 1df4e2f2492..3e1c4ded18e 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__ */ -- GitLab From aa10abd381b9493a88f6b9e111adc79e33d548fa Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:55 +0200 Subject: [PATCH 1197/2509] 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 --- arch/arm/plat-mxc/Makefile | 2 + arch/arm/plat-mxc/iomux-mx1-mx2.c | 156 ++++++++++ include/asm-arm/arch-mxc/iomux-mx1-mx2.h | 372 +++++++++++++++++++++++ 3 files changed, 530 insertions(+) create mode 100644 arch/arm/plat-mxc/iomux-mx1-mx2.c create mode 100644 include/asm-arm/arch-mxc/iomux-mx1-mx2.h diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index e3cc25c6d46..db66e9ae841 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 00000000000..1985571eb40 --- /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 00000000000..076d37b38eb --- /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 */ -- GitLab From eea643f7ff04fe17c3ff71d41a9487c0753bd821 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:56 +0200 Subject: [PATCH 1198/2509] 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 --- arch/arm/mach-mx2/Kconfig | 5 +++ arch/arm/mach-mx2/Makefile | 7 ++++ arch/arm/mach-mx2/Makefile.boot | 3 ++ arch/arm/mach-mx2/generic.c | 74 +++++++++++++++++++++++++++++++++ arch/arm/mach-mx2/system.c | 63 ++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 arch/arm/mach-mx2/Kconfig create mode 100644 arch/arm/mach-mx2/Makefile create mode 100644 arch/arm/mach-mx2/Makefile.boot create mode 100644 arch/arm/mach-mx2/generic.c create mode 100644 arch/arm/mach-mx2/system.c diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig new file mode 100644 index 00000000000..23def05fea0 --- /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 00000000000..937192dc57a --- /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 00000000000..696831dcd48 --- /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 00000000000..07875cf00de --- /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 00000000000..99304645299 --- /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); +} -- GitLab From 32dc80c9cb13a7ce686bcc26efcf39e35719b466 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:56 +0200 Subject: [PATCH 1199/2509] 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 --- arch/arm/mach-mx2/crm_regs.h | 273 ++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/hardware.h | 3 + include/asm-arm/arch-mxc/iim.h | 77 ++++++++ 3 files changed, 353 insertions(+) create mode 100644 arch/arm/mach-mx2/crm_regs.h create mode 100644 include/asm-arm/arch-mxc/iim.h diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h new file mode 100644 index 00000000000..a40a9b950ce --- /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 4ed2d8072d0..f841127ef75 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 00000000000..315bffadafd --- /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__ */ -- GitLab From fc80a5e3d0480d416e4f53b0680aaf525b5076d8 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:57 +0200 Subject: [PATCH 1200/2509] 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 --- arch/arm/mach-mx2/Makefile | 2 +- arch/arm/mach-mx2/devices.c | 231 ++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mx2/devices.c diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 937192dc57a..db4d9c6f273 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 00000000000..a1f44c3c531 --- /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)); +} -- GitLab From 604cbadce2292d979749e2f5c6c3f75ee10f4c9e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:58 +0200 Subject: [PATCH 1201/2509] MX2 add support for mx2 in i.MX serial driver add support for mx2 in i.MX serial driver Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/Makefile | 2 +- arch/arm/mach-mx2/serial.c | 177 +++++++++++++++++++++++++++++++++++++ drivers/serial/imx.c | 6 +- 3 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-mx2/serial.c diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index db4d9c6f273..f8f8ecb01c9 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 00000000000..570c02b8e5d --- /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 549440b098b..64acb39a51b 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" -- GitLab From f31405cc4cc568baad28273c7f45b0563b57a17d Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:59 +0200 Subject: [PATCH 1202/2509] i.MX27 CPU: Add basic i.MX27 CPU support Add basic i.MX27 CPU support Signed-off-by: Juergen Beisert --- arch/arm/mach-mx2/Kconfig | 6 + arch/arm/mach-mx2/Makefile | 2 + arch/arm/mach-mx2/cpu_imx27.c | 63 ++++++ include/asm-arm/arch-mxc/hardware.h | 3 + include/asm-arm/arch-mxc/mx27.h | 302 ++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/mxc.h | 4 + 6 files changed, 380 insertions(+) create mode 100644 arch/arm/mach-mx2/cpu_imx27.c create mode 100644 include/asm-arm/arch-mxc/mx27.h diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 23def05fea0..6e7d724e323 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 f8f8ecb01c9..c9eac3b1e13 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 00000000000..d6b5c2e3377 --- /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 f841127ef75..37cddbaaade 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 00000000000..212ecc24662 --- /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 3e1c4ded18e..332eda4dbd3 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__ */ -- GitLab From c46f5856517c2d4f438df87dac81f2295931ee93 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:59 +0200 Subject: [PATCH 1203/2509] 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 --- arch/arm/mach-mx2/Makefile | 1 + arch/arm/mach-mx2/clock_imx27.c | 1626 +++++++++++++++++++++++++++++++ 2 files changed, 1627 insertions(+) create mode 100644 arch/arm/mach-mx2/clock_imx27.c diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index c9eac3b1e13..74fb9b3eb06 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 00000000000..0a29ef29c73 --- /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; +} -- GitLab From 80eedae6f0322dafc749140b67986b2472473745 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: [PATCH 1204/2509] 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 --- arch/arm/configs/imx27ads_defconfig | 826 +++++++++++++++++++++++ arch/arm/mach-mx2/Kconfig | 7 + arch/arm/mach-mx2/Makefile | 2 + arch/arm/mach-mx2/mx27ads.c | 304 +++++++++ include/asm-arm/arch-mxc/board-mx27ads.h | 354 ++++++++++ include/asm-arm/arch-mxc/debug-macro.S | 4 +- 6 files changed, 1496 insertions(+), 1 deletion(-) create mode 100644 arch/arm/configs/imx27ads_defconfig create mode 100644 arch/arm/mach-mx2/mx27ads.c create mode 100644 include/asm-arm/arch-mxc/board-mx27ads.h diff --git a/arch/arm/configs/imx27ads_defconfig b/arch/arm/configs/imx27ads_defconfig new file mode 100644 index 00000000000..bcd95b8dd2d --- /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 6e7d724e323..6f98355d686 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 74fb9b3eb06..f6764eb6471 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 00000000000..a9ff01fff13 --- /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 00000000000..61e66dac90e --- /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 5add48b6665..c6c56805143 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? -- GitLab From 7e5e9f5457f5cd019fd7e2f3da94e9fc72cc9ff6 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: [PATCH 1205/2509] 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 --- arch/arm/configs/pcm038_defconfig | 1008 +++++++++++++++++++++++ arch/arm/mach-mx2/Kconfig | 7 + arch/arm/mach-mx2/Makefile | 1 + arch/arm/mach-mx2/pcm038.c | 200 +++++ include/asm-arm/arch-mxc/board-pcm038.h | 36 + include/asm-arm/arch-mxc/debug-macro.S | 3 + 6 files changed, 1255 insertions(+) create mode 100644 arch/arm/configs/pcm038_defconfig create mode 100644 arch/arm/mach-mx2/pcm038.c create mode 100644 include/asm-arm/arch-mxc/board-pcm038.h diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig new file mode 100644 index 00000000000..6b798c215ca --- /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 6f98355d686..4c19e1c7947 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 f6764eb6471..f8d3836ee2f 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 00000000000..46fc026138c --- /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 00000000000..300467e8db6 --- /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 c6c56805143..575087f8561 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -24,6 +24,9 @@ #endif #ifdef CONFIG_MACH_MX27ADS #include +#endif +#ifdef CONFIG_MACH_PCM038 +#include #endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 -- GitLab From ff6552e4f3505da9c2886098773146be71c872e3 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:01 +0200 Subject: [PATCH 1206/2509] 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 --- arch/arm/mach-mx2/Kconfig | 14 +++++++++++ arch/arm/mach-mx2/Makefile | 1 + arch/arm/mach-mx2/pcm038.c | 4 ++++ arch/arm/mach-mx2/pcm970-baseboard.c | 32 +++++++++++++++++++++++++ include/asm-arm/arch-mxc/board-pcm038.h | 5 ++++ 5 files changed, 56 insertions(+) create mode 100644 arch/arm/mach-mx2/pcm970-baseboard.c diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 4c19e1c7947..1eaa97cb716 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 f8d3836ee2f..382d86080e8 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 46fc026138c..a9a28f58e71 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 00000000000..028ac4d3368 --- /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 300467e8db6..750c62afd90 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__ */ -- GitLab From 1bd55a436f1f90de0e7f476e514e01bd67497b88 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:02 +0200 Subject: [PATCH 1207/2509] 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 --- arch/arm/Makefile | 1 + arch/arm/mm/Kconfig | 4 ++-- arch/arm/plat-mxc/Kconfig | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e72db27e0ba..009d4feb954 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 33ed048502a..68ea247bdd8 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 bb6e12738fb..e14eaad11dd 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 -- GitLab From 5e374fb62621aca9522f76c2317c9acda75a8e88 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 1 Jul 2008 13:12:04 +0200 Subject: [PATCH 1208/2509] generic-ipi: fixlet create proper stackframe. Signed-off-by: Ingo Molnar --- arch/x86/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 56546e8a13a..361b7a4c640 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(); -- GitLab From bdb2b8cab4392ce41ddfbd6773a3da3334daf836 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jun 2008 14:03:14 -0400 Subject: [PATCH 1209/2509] [SCSI] erase invalid data returned by device This patch (as1108) fixes a problem that can occur with certain USB mass-storage devices: They return invalid data together with a residue indicating that the data should be ignored. Rather than leave the invalid data in a transfer buffer, where it can get misinterpreted, the patch clears the invalid portion of the buffer. This solves a problem (wrong write-protect setting detected) reported by Maciej Rutecki and Peter Teoh. Signed-off-by: Alan Stern Tested-by: Peter Teoh Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a82d2fe80fb..cbf55d59a54 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -207,6 +207,15 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, */ blk_execute_rq(req->q, NULL, req, 1); + /* + * Some devices (USB mass-storage in particular) may transfer + * garbage data together with a residue indicating that the data + * is invalid. Prevent the garbage from being misinterpreted + * and prevent security leaks by zeroing out the excess data. + */ + if (unlikely(req->data_len > 0 && req->data_len <= bufflen)) + memset(buffer + (bufflen - req->data_len), 0, req->data_len); + ret = req->errors; out: blk_put_request(req); -- GitLab From 265d529cef6fd57698d79b3c0edd3a8178059ea6 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 7 Jul 2008 10:02:36 +0100 Subject: [PATCH 1210/2509] [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 --- fs/gfs2/glock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8d5450f3c3e..cd0aa213fb2 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)) -- GitLab From 209806aba9d540dde3db0a5ce72307f85f33468f Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 7 Jul 2008 10:07:28 +0100 Subject: [PATCH 1211/2509] [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 --- fs/gfs2/glock.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index cd0aa213fb2..13391e54661 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; -- GitLab From 5a2cc50f166babc26103279c4fbc9f2bf73b79de Mon Sep 17 00:00:00 2001 From: eric miao Date: Mon, 26 May 2008 03:28:09 +0100 Subject: [PATCH 1212/2509] [ARM] 5063/1: pxa: add clk support for pxa2xx I2S Signed-off-by: Eric Miao Acked-by: Mark Brown Signed-off-by: Russell King --- sound/soc/pxa/pxa2xx-i2s.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 42507103097..e130346732b 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 -- GitLab From 9f17f2874834f4cdbe48cc05676d8f7558793204 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sun, 22 Jun 2008 04:27:28 +0100 Subject: [PATCH 1213/2509] [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 --- drivers/video/pxafb.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3ee314beacc..3682bbd7e50 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"); -- GitLab From f1b23586c1f50d4c5684e56395140ec1cd8b688d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 30 Jun 2008 18:08:11 +0100 Subject: [PATCH 1214/2509] [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 --- arch/arm/mach-pxa/irq.c | 1 - drivers/i2c/busses/i2c-pxa.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index a9a0c3fab15..fbff557bb22 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 eb69fbadc9c..eb26d2aca8b 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; -- GitLab From 5e329d1c7f5fe6adfee99c783fa98bda7dae8ac5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 6 Jun 2008 10:12:37 +0100 Subject: [PATCH 1215/2509] [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 --- include/asm-arm/arch-pxa/pxa2xx-gpio.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-arm/arch-pxa/pxa2xx-gpio.h b/include/asm-arm/arch-pxa/pxa2xx-gpio.h index 763313c5e6b..a6e60f69161 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 */ -- GitLab From 4ed47896935573c8423d05bddda3f269d6e6c613 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 Jul 2008 16:11:06 +0100 Subject: [PATCH 1216/2509] [ARM] mach-types update Update mach-types. Remove invalid or incorrect entries. Signed-off-by: Russell King --- arch/arm/tools/mach-types | 126 +++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 17 deletions(-) diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 207a8b5a0c4..0be5630ff56 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 -- GitLab From 4ab9897172b7ff3a1a37b65b53f71c5795a577b0 Mon Sep 17 00:00:00 2001 From: Ramax Lo Date: Mon, 7 Jul 2008 18:12:36 +0100 Subject: [PATCH 1217/2509] [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 --- arch/arm/mach-s3c2440/Kconfig | 5 + arch/arm/mach-s3c2440/Makefile | 1 + arch/arm/mach-s3c2440/mach-at2440evb.c | 162 +++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 arch/arm/mach-s3c2440/mach-at2440evb.c diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index dcaa4dbebb3..25de042ab99 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 c81ed6248dc..0b4440e79b9 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 00000000000..99f660564c1 --- /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 -- GitLab From 66493c2d88d5086399c5a485d6e41cb76b241a1f Mon Sep 17 00:00:00 2001 From: Ramax Lo Date: Mon, 7 Jul 2008 18:12:37 +0100 Subject: [PATCH 1218/2509] [ARM] AT2440EVB: Add DM9000A network controller support. Add DM9000AEP network controller support for AT2440EVB. Signed-off-by: Ramax Lo Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2440/mach-at2440evb.c | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index 99f660564c1..f5e3c7f2763 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) -- GitLab From 29a7bcfd144a577b5cdb3b735c58e20d0489b30e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:38 +0100 Subject: [PATCH 1219/2509] [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 --- arch/arm/mach-s3c2443/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index b42f956738d..24da92417a1 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; } -- GitLab From ba7622a19fabb853b8bbb918a5d76557f88e4274 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:39 +0100 Subject: [PATCH 1220/2509] [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 --- arch/arm/mach-s3c2443/clock.c | 54 ++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 24da92417a1..d34f3d32eba 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", -- GitLab From 2e16c27aa379793c354012e5fae0aae89103b19b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:40 +0100 Subject: [PATCH 1221/2509] [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 --- arch/arm/mach-s3c2443/clock.c | 39 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index d34f3d32eba..17f064fabda 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", -- GitLab From 196a047574e1465b89bc41fda573efc9b9be70e5 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:41 +0100 Subject: [PATCH 1222/2509] [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 --- arch/arm/mach-s3c2410/mach-n30.c | 39 +++++++++++++------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 621f548da61..fc54e07ccac 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: -*/ -- GitLab From d088e5fe586287da003341e7bbfdad15e0f432f7 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:42 +0100 Subject: [PATCH 1223/2509] [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 --- arch/arm/mach-s3c2410/mach-n30.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index fc54e07ccac..8edc0c0eb04 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. */ -- GitLab From 620657500263cca4a4d9845eeaeba47e03447075 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:43 +0100 Subject: [PATCH 1224/2509] [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 --- arch/arm/mach-s3c2410/mach-n30.c | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 8edc0c0eb04..631f3a9e7a6 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 = { -- GitLab From 865cc639a636b58612becfb6a337945c022596ac Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:44 +0100 Subject: [PATCH 1225/2509] [ARM] Acer n30: LED support. Add support for the LEDs on the Acer N30. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 631f3a9e7a6..e1351a7b40e 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 = { -- GitLab From 9579087331ee0cd220d29aa5bda79ff55b33c228 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:45 +0100 Subject: [PATCH 1226/2509] [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 --- arch/arm/mach-s3c2410/Kconfig | 5 +- arch/arm/mach-s3c2410/mach-n30.c | 145 ++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 1a7d01b4744..99fdc736698 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 e1351a7b40e..621b343adbe 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 -- GitLab From e43f238390168a13416d4f21803f76b1ff45fb95 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:46 +0100 Subject: [PATCH 1227/2509] [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 --- arch/arm/mach-s3c2410/mach-n30.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 621b343adbe..476b15c089a 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); -- GitLab From 9a2ddb7866c2887352e85c6443dfb5e679140aff Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:47 +0100 Subject: [PATCH 1228/2509] [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 --- arch/arm/mach-s3c2410/mach-n30.c | 139 +++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 476b15c089a..450d10823f8 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)); } -- GitLab From a67557801aeda1f9f19e4606a00c948f6054417c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:48 +0100 Subject: [PATCH 1229/2509] [ARM] Acer n30: Minor style and indentation fixes. Minor style fixes. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/mach-n30.c | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 450d10823f8..43c2e915c5b 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 = { -- GitLab From 7ba06b17a1931b2c9e1bee525a8c36920f5be0e0 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:49 +0100 Subject: [PATCH 1230/2509] [ARM] s3c2410_defconfig: update for current build Update the s3c2410_defconfig for the current set of added patches. Signed-off-by: Ben Dooks --- arch/arm/configs/s3c2410_defconfig | 34 ++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 1a0434b0079..3796397fde2 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 -- GitLab From 2f8209788d774c66efb5e2991affc06b1d1c7314 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Thu, 26 Jun 2008 01:30:41 +0200 Subject: [PATCH 1231/2509] [ARM] Orion: add Netgear WNR854T support Signed-off-by: Imre Kaloz Signed-off-by: Lennert Buytenhek --- arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/wnr854t-setup.c | 164 ++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 arch/arm/mach-orion5x/wnr854t-setup.c diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index f8b91ea3eb7..99b35b718b8 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 65b2fc6a355..26a62ede37a 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 00000000000..1af093ff8cf --- /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 -- GitLab From 70129132322cdbb6683ab9e90419cd5a6f8294d3 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 30 Jun 2008 14:25:24 -0400 Subject: [PATCH 1232/2509] [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 --- arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/rd88f5181l-ge-setup.c | 172 ++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 arch/arm/mach-orion5x/rd88f5181l-ge-setup.c diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 99b35b718b8..709e901b9f8 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 26a62ede37a..ec8374a913b 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 00000000000..b56447d32e1 --- /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 -- GitLab From 6b5cdf0f6d4dc3d98de20d6b0abe8500046f1cb1 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 27 Jun 2008 18:56:22 -0400 Subject: [PATCH 1233/2509] [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 --- arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c | 161 +++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 709e901b9f8..ddcd41b15d1 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 ec8374a913b..fcc48a8864f 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 00000000000..d50e3650a09 --- /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 -- GitLab From 2e1117d307dba8185a72bac94e57f057e70590ca Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Mon, 7 Jul 2008 21:23:09 +0300 Subject: [PATCH 1234/2509] [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 --- arch/arm/configs/orion5x_defconfig | 4 +-- arch/arm/mach-orion5x/mv2120-setup.c | 45 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 8a7cabfae57..9578b5d9f9c 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 f1dcad36b13..55f3b0fdef8 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 || -- GitLab From 188237e28d7fece0471640ba86f6d8cd164ed085 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Wed, 2 Jul 2008 06:06:32 -1100 Subject: [PATCH 1235/2509] [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 --- arch/arm/mm/proc-feroceon.S | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 63ca1ea5c26..f2e5884c513 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 -- GitLab From c6c4f070a61b2b6e5cd317a5fbf25255878688a2 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 3 Jul 2008 09:49:39 -0700 Subject: [PATCH 1236/2509] 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 --- arch/sparc64/kernel/pci.c | 2 +- include/linux/pci.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 112b09f16f3..d00a3656c28 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 96ebaa8d80e..4c80dc3f299 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); } -- GitLab From 3737b2b1046900660b42e25c904b85e78139d25b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:30:55 +0200 Subject: [PATCH 1237/2509] 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 --- drivers/acpi/bus.c | 11 +++++++++++ include/acpi/acpi_bus.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a6dbcf4d9ef..b9b69d9629b 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 db90a74f871..0c21ea3bb67 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); -- GitLab From 961d9120fa6f078492a1c762dd91f2c097e56c83 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:32:02 +0200 Subject: [PATCH 1238/2509] 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 --- drivers/pci/pci-acpi.c | 19 +++++++++++++------ drivers/pci/pci.c | 40 ++++++++++++++++++++++++++++++---------- drivers/pci/pci.h | 26 ++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 056ea80ee27..e4df71ab79b 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 8e8ecc1da93..f8074525267 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 e0eff35825a..0cd2e719933 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); -- GitLab From 44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:32:52 +0200 Subject: [PATCH 1239/2509] 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 --- drivers/pci/pci-acpi.c | 16 +++-- drivers/pci/pci.c | 150 ++++++++++++++++++++++++++++------------- 2 files changed, 114 insertions(+), 52 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e4df71ab79b..6bc0d8c870a 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 f8074525267..20e28077b96 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 @@ -529,6 +512,81 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) return 0; } +/** + * 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 -- GitLab From 77e766099efc29d8b01db4b8244ff64fa3d3d0ca Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:33:34 +0200 Subject: [PATCH 1240/2509] 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 --- drivers/acpi/power.c | 118 +++++++++++++++++++++++++----------- drivers/acpi/scan.c | 42 ++----------- drivers/acpi/sleep/wakeup.c | 2 +- include/acpi/acpi_drivers.h | 4 +- 4 files changed, 92 insertions(+), 74 deletions(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 81e4f081a4a..2e959aa1ef0 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 6d85289f1c1..f276890cfde 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 ed8e41becf0..7422a221394 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 9757a040a50..e5f38e5ce86 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); -- GitLab From 0af4b8c4fb31193dc666f4893107a18fef82baab Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:34:11 +0200 Subject: [PATCH 1241/2509] 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 --- drivers/acpi/power.c | 24 ++++++++++++++++++++++-- include/acpi/acpi_bus.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 2e959aa1ef0..4ab21cb1c8c 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 0c21ea3bb67..071daf8db60 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 */ }; -- GitLab From eb9d0fe40e313c0a74115ef456a2e43a6c8da72f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:34:48 +0200 Subject: [PATCH 1242/2509] 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 --- drivers/acpi/bus.c | 11 +++ drivers/acpi/glue.c | 2 + drivers/acpi/sleep/main.c | 25 ++++++ drivers/acpi/sleep/wakeup.c | 11 ++- drivers/base/power/sysfs.c | 3 - drivers/pci/pci-acpi.c | 20 +++++ drivers/pci/pci.c | 169 ++++++++++++++++++++++++++---------- drivers/pci/pci.h | 8 ++ drivers/pci/probe.c | 47 +--------- include/acpi/acpi_bus.h | 2 + include/linux/pm_wakeup.h | 26 ++---- 11 files changed, 208 insertions(+), 116 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b9b69d9629b..fc1110d6a07 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 06f8634fe58..87c5d456e18 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 4addf8ad50a..af7f4663dea 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 7422a221394..38655eb132d 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 d11f74b038d..596aeecfdff 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 6bc0d8c870a..7764768b6a0 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 20e28077b96..a6b1b6f96ab 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 @@ -1035,6 +1047,56 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) return pcibios_set_pcie_reset_state(dev, 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 @@ -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 0cd2e719933..b08dfc9746a 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 2f0ae70710d..b1724cf31b6 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 071daf8db60..7ab5a611e43 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 f0d0b2cb8d2..3af0c8d05cd 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 */ -- GitLab From 404cc2d8ce41ed4031958fba8e633767e8a2e028 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:35:26 +0200 Subject: [PATCH 1243/2509] 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 --- drivers/pci/pci.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 2 ++ 2 files changed, 85 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a6b1b6f96ab..1b0ec45e993 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1146,6 +1146,87 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) return pme_done ? 0 : error; } +/** + * 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 4c80dc3f299..52ac06dcce9 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); -- GitLab From 337001b6c42938f49a880b1b8306c3ed771a7e61 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:36:24 +0200 Subject: [PATCH 1244/2509] 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 --- drivers/pci/pci.c | 118 +++++++++++++++++---------------------- include/linux/pci.h | 8 ++- include/linux/pci_regs.h | 1 + 3 files changed, 60 insertions(+), 67 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b0ec45e993..e632a58ba5d 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 52ac06dcce9..68a29f0f274 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 c0c1223c919..19958b92990 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 */ -- GitLab From a05fe0389b72f43b9e29d6fbfc5885084be2f96f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 8 Jul 2008 22:15:40 +1000 Subject: [PATCH 1245/2509] 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 --- arch/sparc64/kernel/stacktrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 49656ed6ab1..b3e3737750d 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include -- GitLab From 081a5bcb39b455405d58f79bb3c9398a9d4477ed Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 7 Jul 2008 11:24:06 -0500 Subject: [PATCH 1246/2509] [SCSI] mptspi: fix oops in mptspi_dv_renegotiate_work() The problem here is that if the ioc faults too early in the bring up sequence (as it usually does for an irq routing problem), ioc_reset gets called before the scsi host is even allocated. This causes an oops when it later schedules a renegotiation. Fix this by checking ioc->sh before trying to renegotiate. Cc: "Moore, Eric" Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/message/fusion/mptspi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 25bcfcf36f2..1effca4e40e 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -1266,13 +1266,18 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) static int mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); int rc; rc = mptscsih_ioc_reset(ioc, reset_phase); - if (reset_phase == MPT_IOC_POST_RESET) + /* only try to do a renegotiation if we're properly set up + * if we get an ioc fault on bringup, ioc->sh will be NULL */ + if (reset_phase == MPT_IOC_POST_RESET && + ioc->sh) { + struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); + mptspi_dv_renegotiate(hd); + } return rc; } -- GitLab From f7a1b86095bf7fd1578ef54067545b9cb7084713 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 15:00:54 +0100 Subject: [PATCH 1247/2509] 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 --- include/acpi/acpi_bus.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 7ab5a611e43..a5ac0bc7f52 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 */ -- GitLab From 46deed69b34d0aa6065e92ad79685e103d4ccd35 Mon Sep 17 00:00:00 2001 From: Luke Browning Date: Mon, 16 Jun 2008 11:36:43 +1000 Subject: [PATCH 1248/2509] 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 --- arch/powerpc/platforms/cell/spufs/file.c | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index f74259979cb..fc595d0db21 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, }, {}, }; -- GitLab From 2442a8ba5abe2c27c572bc522da1c33df98c6ec7 Mon Sep 17 00:00:00 2001 From: Luke Browning Date: Fri, 6 Jun 2008 11:26:54 +0800 Subject: [PATCH 1249/2509] 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 --- arch/powerpc/platforms/cell/spufs/sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index e929e70a84e..afb92d4fbcf 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); -- GitLab From 87ff6090bfe416c71730654ab53cd4ecffdd675e Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 1 Jul 2008 10:22:50 +1000 Subject: [PATCH 1250/2509] 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 --- arch/powerpc/platforms/cell/spufs/context.c | 12 +++++------ arch/powerpc/platforms/cell/spufs/file.c | 24 ++++++++++----------- arch/powerpc/platforms/cell/spufs/spufs.h | 7 ++++++ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 177735f7931..6653ddbed04 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 fc595d0db21..d0a497d9140 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 454c277c145..433dece5c82 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, -- GitLab From 23d893f51cde7013e4c29094da2237cce4f20035 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 30 Jun 2008 12:17:28 +1000 Subject: [PATCH 1251/2509] 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 --- arch/powerpc/platforms/cell/spufs/file.c | 4 ++-- arch/powerpc/platforms/cell/spufs/inode.c | 7 ++++--- arch/powerpc/platforms/cell/spufs/spufs.h | 11 +++++++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index d0a497d9140..9533a8ad33f 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 f407b247185..c662ca78360 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 433dece5c82..413605406bd 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; -- GitLab From 6f7dde812defe5bc49cf463ac1579ffeda5cbfd4 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 30 Jun 2008 14:38:37 +1000 Subject: [PATCH 1252/2509] 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 --- arch/powerpc/platforms/cell/spufs/file.c | 36 +++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 9533a8ad33f..fee645b580c 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, }, -- GitLab From 2c3e47871d18f93b8bc2892fb41432111201356d Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 3 Jul 2008 11:42:20 +1000 Subject: [PATCH 1253/2509] 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 --- arch/powerpc/platforms/cell/spufs/file.c | 5 ++- arch/powerpc/platforms/cell/spufs/inode.c | 40 +++++++++++++++++++---- arch/powerpc/platforms/cell/spufs/spufs.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index fee645b580c..99c73066b82 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 c662ca78360..7123472801d 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 413605406bd..8ae8ef9dfc2 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; -- GitLab From 88b90c96b787ecb5c72384b6873468f814cce650 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Wed, 2 Jul 2008 04:17:05 +1000 Subject: [PATCH 1254/2509] 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 --- arch/powerpc/platforms/ps3/system-bus.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 43c493fca2d..cf215e981c3 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; } -- GitLab From fabb657005edbbcb0d13ee49a40f1f4b042a1d19 Mon Sep 17 00:00:00 2001 From: Maxim Shchetynin Date: Sat, 5 Jul 2008 05:05:39 +1000 Subject: [PATCH 1255/2509] 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 --- arch/powerpc/platforms/cell/spufs/sched.c | 6 ++++++ include/asm-powerpc/spu.h | 1 + 2 files changed, 7 insertions(+) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index afb92d4fbcf..34654743363 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 99348c1f4ca..8b2eb044270 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; }; -- GitLab From c8692362db3db3a6f644e05a477161d967430aac Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:41 +1000 Subject: [PATCH 1256/2509] 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 --- arch/powerpc/kernel/dma_64.c | 2 +- arch/powerpc/kernel/iommu.c | 7 +++---- include/asm-powerpc/iommu.h | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 3a317cb0636..739744508c6 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 0c663669bc3..ccf00fe9cee 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 852e15f51a1..65f6682bee8 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); -- GitLab From 3affedc4e1ce837033b6c5e9289d2ce2f5a62d31 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:42 +1000 Subject: [PATCH 1257/2509] 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 --- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/dma_64.c | 34 ++++--- arch/powerpc/kernel/ibmebus.c | 12 ++- arch/powerpc/kernel/iommu.c | 11 ++- arch/powerpc/platforms/iseries/iommu.c | 4 +- arch/powerpc/platforms/ps3/system-bus.c | 17 ++-- include/asm-powerpc/dma-mapping.h | 116 ++++++++++++++++++------ include/asm-powerpc/iommu.h | 12 ++- 8 files changed, 144 insertions(+), 63 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f2a0f50146e..462c86a4eef 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 739744508c6..3ae0c35d21f 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 9971159c804..e3b1fcd6d99 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 ccf00fe9cee..8c68ee9e5d1 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 11fa3c772ed..ab5d8687c3c 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 cf215e981c3..d66c3628a11 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 bbefb69bfb6..de1395023cb 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 65f6682bee8..51ecfef8d84 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); -- GitLab From 7e5f8105030038de94b44a74cd7b64dd000830fc Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:44 +1000 Subject: [PATCH 1258/2509] 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 --- arch/powerpc/platforms/cell/iommu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 45646b2b4af..eeacb3a52ca 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 -- GitLab From 3a4c6f0b1540811110a59112b4c83f55c229728c Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:45 +1000 Subject: [PATCH 1259/2509] 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 --- arch/powerpc/kernel/dma_64.c | 9 --------- include/asm-powerpc/dma-mapping.h | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 3ae0c35d21f..ae5708e3a31 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 de1395023cb..74c54978098 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 */ -- GitLab From 058c78f4ba89df7b2de82ac271452f09e2b8fa05 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2008 13:44:31 +1000 Subject: [PATCH 1260/2509] 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 --- arch/powerpc/kernel/process.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 85e557300d8..0a4eb081159 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; } -- GitLab From e5093ff05d36c64e8f36a9ddb26358256dc133ea Mon Sep 17 00:00:00 2001 From: Srinivasa Ds Date: Tue, 8 Jul 2008 00:22:27 +1000 Subject: [PATCH 1261/2509] 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 --- include/asm-powerpc/processor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 061cd17ba83..101ed87f7d8 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) -- GitLab From b845f313d78e4e259ec449909e3bbadf77b53a6d Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:51 +1000 Subject: [PATCH 1262/2509] 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 --- include/linux/mman.h | 29 ++++++++++++++++++++++++++++- mm/mmap.c | 5 +++-- mm/mprotect.c | 2 +- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/include/linux/mman.h b/include/linux/mman.h index dab8892e6ff..30d1073bac3 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -33,6 +33,32 @@ static inline void vm_unacct_memory(long pages) vm_acct_memory(-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 @@ -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 3354fdd83d4..1d102b956fd 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 a5bf31c2737..ecfaa5844b5 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; -- GitLab From aba46c5027cb59d98052231b36efcbbde9c77a1d Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:52 +1000 Subject: [PATCH 1263/2509] 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 --- include/asm-powerpc/mman.h | 2 ++ include/asm-powerpc/pgtable-ppc64.h | 3 +++ include/linux/mm.h | 1 + 3 files changed, 6 insertions(+) diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index 24cf664a829..0c46bf2c7d5 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 b2754d46be4..d09599cccb3 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 586a943cab0..689184446fc 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 -- GitLab From 379070491e1e744a59e69e5bcf3765012d15ecb4 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:53 +1000 Subject: [PATCH 1264/2509] 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 --- include/asm-powerpc/cputable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 3171ac904b9..4fd76898975 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 | \ -- GitLab From ef3d3246a0d06be622867d21af25f997aeeb105f Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:54 +1000 Subject: [PATCH 1265/2509] 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 --- arch/powerpc/kernel/syscalls.c | 3 +++ include/asm-powerpc/mman.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 4fe69ca2448..c04832c4a02 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 0c46bf2c7d5..f8a32e20ba0 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 */ -- GitLab From 801eb73f45371accc78ca9d6d22d647eeb722c11 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:55 +1000 Subject: [PATCH 1266/2509] 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 --- arch/powerpc/platforms/pseries/lpar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 3b4651b6ee0..38b5927b362 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); -- GitLab From 05781ccd74c63c6c8567f99101587d5c07c163e0 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Tue, 8 Jul 2008 08:03:11 +1000 Subject: [PATCH 1267/2509] 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 --- arch/powerpc/boot/dts/canyonlands.dts | 8 +- arch/powerpc/boot/dts/glacier.dts | 8 +- arch/powerpc/boot/dts/haleakala.dts | 4 +- arch/powerpc/boot/dts/katmai.dts | 2 +- arch/powerpc/boot/dts/kilauea.dts | 8 +- arch/powerpc/boot/dts/makalu.dts | 8 +- arch/powerpc/boot/dts/rainier.dts | 4 +- arch/powerpc/boot/dts/sequoia.dts | 4 +- arch/powerpc/boot/dts/taishan.dts | 8 +- drivers/net/ibm_newemac/core.c | 61 +++++++++++----- drivers/net/ibm_newemac/core.h | 83 ++++++++++++++++++++- drivers/net/ibm_newemac/debug.c | 52 +++++++++---- drivers/net/ibm_newemac/emac.h | 101 ++++++++++++++++++-------- 13 files changed, 259 insertions(+), 92 deletions(-) diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index f9fe0325215..79fe412c11c 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 463650c5f61..24cf0dba120 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 2c2fceaabbc..513bc43a71a 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 b94bf61b9bc..077819bc3cb 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 3ed6a8fee1d..dececc4b5ff 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 1dfcd7ed199..945508c7e7d 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 2afb63a42ea..9684c80e409 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 149dabc5521..72d15f075d3 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 d4867ded869..058438f9629 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 5d2108c5ac7..ed24a1d607d 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 22309046676..6545e69d12c 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 86b756a3078..775c850a425 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 91cb096ab40..0afc2cf5c52 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 -- GitLab From 1b17adf19b4d66858f366acd82b4e81cba5edc93 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 8 Jul 2008 08:42:09 +1000 Subject: [PATCH 1268/2509] 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 --- arch/powerpc/kernel/ibmebus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index e3b1fcd6d99..9d42eb57aea 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); -- GitLab From c1cb299ead405f0ac065c4430729549b187e5b32 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 8 Jul 2008 18:43:41 +1000 Subject: [PATCH 1269/2509] 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 --- arch/powerpc/kernel/signal_32.c | 39 ++++++++++++++++++++++++++++++++- arch/powerpc/kernel/signal_64.c | 36 ++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 9991e2a58bf..6f6810db0a7 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -67,6 +67,13 @@ #define mcontext mcontext32 #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 @@ -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 93ebfb6944b..5f9d2ef2e24 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -267,6 +267,13 @@ static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) return err; } +/* + * 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 */ @@ -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) -- GitLab From b887ec620a7575f54fa025d38fa1008dc8a3b12a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 8 Jul 2008 18:53:03 +1000 Subject: [PATCH 1270/2509] 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 --- arch/powerpc/kernel/align.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index c95954c8145..f22b5d0a4a9 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 -- GitLab From cde274c0c789404df8ece3f9e7d6506caf0127e2 Mon Sep 17 00:00:00 2001 From: Mike Mason Date: Wed, 9 Jul 2008 02:04:35 +1000 Subject: [PATCH 1271/2509] 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 --- arch/powerpc/platforms/pseries/eeh.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 6f544ba4b37..c027f0a70a0 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); } /** -- GitLab From c356aa456e8677682aa3cdb4b81d08e814b1a379 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 9 Jul 2008 09:41:52 -0600 Subject: [PATCH 1272/2509] 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 --- arch/powerpc/Kconfig | 13 +++++++++++++ arch/powerpc/boot/Makefile | 3 +++ 2 files changed, 16 insertions(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f2a0f50146e..3216a3a9839 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 df6e62116e3..88d30dbed7b 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%, \ -- GitLab From 57dc9a5747942f131a1a8b36d661fec6e6a5e9f6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 20 Jun 2008 15:35:32 -0400 Subject: [PATCH 1273/2509] NFS: Reduce the stack usage in NFSv4 create operations Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 204 ++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 107 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1293e0acd82..26fbeb3467c 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; } -- GitLab From 0b4aae7aad162ad175ba8a65708332f888066b26 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 20 Jun 2008 17:00:23 -0400 Subject: [PATCH 1274/2509] NFS: Reduce the stack usage in NFSv3 create operations Signed-off-by: Trond Myklebust --- fs/nfs/nfs3proc.c | 271 ++++++++++++++++++++++++---------------------- 1 file changed, 142 insertions(+), 129 deletions(-) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index c3523ad03ed..cf7d4e5927d 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; } -- GitLab From f3d47a3a6a1484a93c8cfe1e8c8d4399c95199c7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 5 Jun 2008 15:17:39 -0400 Subject: [PATCH 1275/2509] 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 --- fs/nfs/write.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f333848fd3b..dc62bc50469 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. -- GitLab From 2116271a347d1181b5497602c2bfada1de8fd53b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 20 May 2008 19:34:39 -0400 Subject: [PATCH 1276/2509] 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 --- fs/nfs/file.c | 20 +++++++++++++++----- fs/nfs/proc.c | 24 ++++++++++++++++++++++++ include/linux/nfs_xdr.h | 1 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index d84a3d8f32a..7c73f06692b 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 03599bfe81c..5c35b02857f 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 24263bb8e0b..8d780de371f 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 *); }; -- GitLab From 8b39f2b41033754e7ba669503d27268beb1b524a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 14 May 2008 19:48:25 -0700 Subject: [PATCH 1277/2509] 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 --- net/sunrpc/clnt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8945307556e..9503b4c177d 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) -- GitLab From b390c2b55c830eb3b64633fa8d8b8837e073e458 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:30:11 -0400 Subject: [PATCH 1278/2509] 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 --- net/sunrpc/clnt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9503b4c177d..1af4f161cda 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; - } } /* -- GitLab From efc91ed0191e3fc62bb1c556ac93fc4e661214d2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:00 -0400 Subject: [PATCH 1279/2509] 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 --- fs/nfs/file.c | 20 ++++++++++++++++++++ fs/nfs/write.c | 12 +++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7c73f06692b..7ac89a845a5 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 dc62bc50469..eea2d2b5278 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; } -- GitLab From 7e5f6146609eb9134fac7d1b6bfee43df1732188 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 25 May 2008 12:59:19 -0400 Subject: [PATCH 1280/2509] 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 --- fs/nfs/write.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index eea2d2b5278..ee6fcdecb87 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; -- GitLab From 0f38b873aeaae698c3693748438547c8493165fb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:01 -0400 Subject: [PATCH 1281/2509] 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 --- net/sunrpc/auth_gss/auth_gss.c | 10 +++++----- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_token.c | 2 +- net/sunrpc/auth_unix.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index cc12d5f5d5d..bf7585b8054 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 60c3dba545d..ef45eba2248 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 5deb4b6e451..035e1dd6af1 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 6cdd241ad26..3308157436d 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 44920b90bdc..46b2647c5bd 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); -- GitLab From b5418383ef13f70528281546d02c15edc03d8567 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:02 -0400 Subject: [PATCH 1282/2509] NFS: do_setlk(): don't flush caches when we have a delegation Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7ac89a845a5..0213c21038f 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; } -- GitLab From 6fb1bc10303c0d88f635d014324432ab6ee49d1b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:04 -0400 Subject: [PATCH 1283/2509] 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 --- fs/Kconfig | 115 ++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index 2694648cbd1..1c16de9611e 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 -- GitLab From 3748f1e447ac1dbf45f33ee7491a008a8bb5cdf0 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:12 -0400 Subject: [PATCH 1284/2509] 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 --- net/sunrpc/clnt.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 1af4f161cda..68ea6dddcf1 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); -- GitLab From b0e1c57ea00302c3ac541ffd37e7db07d13cd674 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:19 -0400 Subject: [PATCH 1285/2509] 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 --- net/sunrpc/clnt.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 68ea6dddcf1..ab8038db8ef 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: -- GitLab From 68a23ee94e3a06819f5a39d64f2e1f3131bab12d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:26 -0400 Subject: [PATCH 1286/2509] 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 --- net/sunrpc/clnt.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index ab8038db8ef..7dda32851ad 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 -- GitLab From 38e886e0c18975543938519254fc9bf0829c75a3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:33 -0400 Subject: [PATCH 1287/2509] 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 --- net/sunrpc/clnt.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 7dda32851ad..7964a98c90e 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); } -- GitLab From cb3997b5a0b21864368bd1bd1d0929f9304fb6d9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:41 -0400 Subject: [PATCH 1288/2509] 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 --- net/sunrpc/clnt.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 7964a98c90e..0530eea37b5 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) -- GitLab From 549177863bac22f23663ee9f70c4e3b9fb269f2c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 27 May 2008 16:29:07 -0400 Subject: [PATCH 1289/2509] 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 --- fs/nfs/dir.c | 3 ++- fs/nfs/file.c | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 982a2064fe4..5d73fbd6707 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 0213c21038f..1789de218cc 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); -- GitLab From b84e06c58fdefdc42931f771dc295e63f4b27365 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:34 -0400 Subject: [PATCH 1290/2509] 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 --- fs/nfs/dir.c | 12 ++++++++++-- fs/nfs/file.c | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5d73fbd6707..24571067bf7 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 1789de218cc..cef36362c9e 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; -- GitLab From cc0dd2d1052aede2946ad1338a8f6f5d5c604740 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:42 -0400 Subject: [PATCH 1291/2509] 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 --- fs/nfs/dir.c | 7 +++++-- fs/nfs/file.c | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 24571067bf7..c962233c094 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 cef36362c9e..202408d96ee 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; -- GitLab From b7eaefaa8722fd98e5c2632640d1abd2b0c83e84 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:50 -0400 Subject: [PATCH 1292/2509] 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 --- fs/nfs/file.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 202408d96ee..6c447a37ede 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; -- GitLab From 6da24bc9cfc645c619992e39aab09747164c9f14 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:58 -0400 Subject: [PATCH 1293/2509] 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 --- fs/nfs/dir.c | 10 ++++----- fs/nfs/direct.c | 4 ++-- fs/nfs/file.c | 59 ++++++++++++++++++++++++++++++------------------- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c962233c094..b1940660502 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 4757a2b326a..08f6b040d28 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 6c447a37ede..78b26f875ee 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; } -- GitLab From 48186c7d5734a6b137f9186b37f6dc98097d0429 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:56:05 -0400 Subject: [PATCH 1294/2509] 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 --- fs/nfs/write.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ee6fcdecb87..21d8a48b624 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, -- GitLab From cd983ef81b9d79573848dabf81277c7314220257 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:56:13 -0400 Subject: [PATCH 1295/2509] 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 --- net/sunrpc/xprt.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e1770f7ba0b..67996bd7fbf 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); -- GitLab From c2d946e55e1be20a7443918e3b7497b905e6b3f7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 01:08:00 +0300 Subject: [PATCH 1296/2509] 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 --- fs/nfs/nfsroot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 531379d3682..15afe3a6c5b 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: -- GitLab From 48b605f83c920d8daa50e43fc2c7f718e04c7bfa Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 10 Jun 2008 15:38:39 -0400 Subject: [PATCH 1297/2509] 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 --- fs/nfs/super.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 614efeed543..b550e921f66 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 */ -- GitLab From b6b6152c46861dd914d0e6cea9c27df057d6e235 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Mon, 9 Jun 2008 16:51:31 -0400 Subject: [PATCH 1298/2509] 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 --- fs/nfsd/nfs4callback.c | 2 +- include/linux/sunrpc/clnt.h | 4 +++- net/sunrpc/clnt.c | 16 +++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 4d4760e687c..702fa577aa6 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 6fff7f82ef1..764fd4c286e 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 0530eea37b5..09631f6e30e 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; } -- GitLab From 720b8f2d6f7de9e16f1217448cc7396e1604e175 Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:33 -0400 Subject: [PATCH 1299/2509] 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 --- net/sunrpc/auth_gss/auth_gss.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index bf7585b8054..ebfd630541f 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; -- GitLab From d25a03cf966f2cf9990dc0bf2a921a554919ea34 Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:34 -0400 Subject: [PATCH 1300/2509] 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 --- net/sunrpc/auth_gss/auth_gss.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index ebfd630541f..834a83199bd 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; -- GitLab From a486aeda9b2b0d944aecce7871b3186379b898de Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:35 -0400 Subject: [PATCH 1301/2509] 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 --- include/linux/sunrpc/sched.h | 1 - net/sunrpc/sched.c | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index d1a5c8c1a0f..64981a2f1ca 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 6eab9bf94ba..6288af05c20 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); } -- GitLab From 659bfcd6dd88919a5ad453f62afbeffcb3106847 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 19:39:41 -0400 Subject: [PATCH 1302/2509] 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 --- fs/nfs/inode.c | 4 ++-- fs/nfs/nfs3proc.c | 2 ++ fs/nfs/nfs4proc.c | 47 +++++++++++++++++++++++------------------------ fs/nfs/proc.c | 2 ++ 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 596c5d8e86f..2e4ab4a5e10 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 cf7d4e5927d..b9c2d995332 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 26fbeb3467c..31a7e4c54a1 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 5c35b02857f..c7605587d0e 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) -- GitLab From b22602a673b1743bba4b62bb404ffd3b269d2f09 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 6 Jun 2008 13:22:25 -0400 Subject: [PATCH 1303/2509] 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 --- net/sunrpc/xprt.c | 1 + net/sunrpc/xprtsock.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 67996bd7fbf..99a52aabe33 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 ddbe981ab51..4486c59c3ac 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); -- GitLab From 46cb650c224bb8e64a749090105d74b9e8eda669 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:32:46 -0400 Subject: [PATCH 1304/2509] 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 --- fs/nfs/file.c | 4 ++-- fs/nfs/nfs3proc.c | 2 -- fs/nfs/nfs4proc.c | 2 -- fs/nfs/proc.c | 2 -- include/linux/nfs_xdr.h | 2 -- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 78b26f875ee..509dcb58959 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 b9c2d995332..1e750e4574a 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 31a7e4c54a1..dfdd19a6d17 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 c7605587d0e..4dbb84df1b6 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 8d780de371f..8c77c11224d 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 *); -- GitLab From 34e8f92831cb5c40b3137e47a3daf4c09016ef02 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:32:25 -0400 Subject: [PATCH 1305/2509] 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 --- fs/nfs/iostat.h | 119 ++++--------------------------------- include/linux/nfs_iostat.h | 119 +++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 106 deletions(-) create mode 100644 include/linux/nfs_iostat.h diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index 6350ecbde58..2ec65e12bfe 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 00000000000..1cb9a3fed2b --- /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 */ -- GitLab From 2e96d2867245668dbdb973729288cf69b9fafa66 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:42:05 -0400 Subject: [PATCH 1306/2509] 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 --- fs/nfs/iostat.h | 8 ++++---- fs/nfs/nfs4proc.c | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index 2ec65e12bfe..a3695281003 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 dfdd19a6d17..058723d9122 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; -- GitLab From f41f741838480aeaa3a189cff6e210503cf9c42d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 17:39:04 -0400 Subject: [PATCH 1307/2509] 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 --- fs/nfs/inode.c | 4 +--- fs/nfs/internal.h | 1 + fs/nfs/nfs3acl.c | 9 ++++++--- fs/nfs/nfs4proc.c | 5 ++++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2e4ab4a5e10..2c23d067e2a 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 04ae867dddb..24241fcbb98 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 9b7362565c0..423842f51ac 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 058723d9122..10f01c05a4e 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; } -- GitLab From ecbb3845dd678364148c1faad32adbc9dd833ef9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:33 -0400 Subject: [PATCH 1308/2509] 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 --- fs/nfs/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b550e921f66..5278eef6111 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" }, -- GitLab From d33e4dfeab5eb0c3c1359cc1a399f2f8b49e18de Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:41 -0400 Subject: [PATCH 1309/2509] 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 --- fs/nfs/super.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 5278eef6111..f824c415c8a 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: -- GitLab From 396cee977f79590673ad51b04f1853e58bc30e7b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:49 -0400 Subject: [PATCH 1310/2509] NFS: missing newline in NFS mount debugging message Clean up. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f824c415c8a..a1065c1a314 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; } -- GitLab From e7d39069e387a12d4c57f4067d9f48c1d29ea900 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 13 Jun 2008 12:12:32 -0400 Subject: [PATCH 1311/2509] 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 --- fs/nfs/write.c | 201 +++++++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 98 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 21d8a48b624..04f51e52e18 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); -- GitLab From e468bae97d243fe0e1515abaa1f7d0edf1476ad0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 13 Jun 2008 13:25:22 -0400 Subject: [PATCH 1312/2509] 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 --- fs/nfs/write.c | 65 ++++++++++++++++++++-------------------- include/linux/nfs_page.h | 9 ++++-- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 04f51e52e18..feca8c64876 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 a1676e19e49..3c60685d972 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 { -- GitLab From cd100725620a8063fbc81bcf16d7c9e71a9583e0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 17 Jun 2008 16:12:00 -0400 Subject: [PATCH 1313/2509] 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 --- fs/nfs/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a1065c1a314..b880db18035 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; -- GitLab From dc04589827f7e1af12714af8bb00e3f3c4c48c62 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:37 -0400 Subject: [PATCH 1314/2509] 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 --- fs/nfs/super.c | 124 +++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b880db18035..c4ee8b3a27c 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1195,6 +1195,67 @@ 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) +{ + 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; -- GitLab From d1aa08257312f1439c1ab7c8a18e3856f9530f46 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:45 -0400 Subject: [PATCH 1315/2509] 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 --- fs/nfs/super.c | 90 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c4ee8b3a27c..ea4abd266a7 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; @@ -1256,6 +1251,85 @@ out_path: return -ENAMETOOLONG; } +/* + * 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 -- GitLab From ce3b7e1906ebbe96753fe090b36de6ffb8e0e0e7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:53 -0400 Subject: [PATCH 1316/2509] 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 --- fs/nfs/super.c | 100 ++++++++++++++++++++++++++++++------------- include/linux/inet.h | 7 +++ 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ea4abd266a7..d27aa1db007 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 1354080cf8c..4cca05c9678 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); -- GitLab From d8e7748ab8322171ebfd78f6155ff35e7d57ac32 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:37:01 -0400 Subject: [PATCH 1317/2509] 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 --- fs/nfs/super.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d27aa1db007..73a8e5970f0 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; -- GitLab From 77e03677ac76d413fbb6d6caaffa1d64877a0c2a Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Tue, 24 Jun 2008 20:25:57 +0300 Subject: [PATCH 1318/2509] 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 --- fs/nfs/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 10f01c05a4e..4451287a81d 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); -- GitLab From ee84dfc45467fd8e5ce04fa2813d98e0aebe465c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Jun 2008 10:03:10 -0400 Subject: [PATCH 1319/2509] 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 --- fs/nfs/callback.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index c1e7c830062..9e713d2d5d7 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) -- GitLab From 5afc597c5f0bd184457e49b9a330fcb37b69db11 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Jun 2008 10:03:11 -0400 Subject: [PATCH 1320/2509] 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 --- fs/nfs/callback.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 9e713d2d5d7..f447f4b4476 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); } -- GitLab From 877fcf103982e52a59a1035378b4c0b8c63fe004 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:23 -0400 Subject: [PATCH 1321/2509] 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 --- net/sunrpc/rpcb_clnt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index e6fb21b19b8..cf2b91613ac 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; } -- GitLab From fc200e794d723bc88c39859e8f096b717532f9c9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:31 -0400 Subject: [PATCH 1322/2509] 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 --- net/sunrpc/rpcb_clnt.c | 49 +++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index cf2b91613ac..b23a719aca3 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 }; -- GitLab From 6a774051573042cdeb57e81f77b36c25e5856739 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:39 -0400 Subject: [PATCH 1323/2509] 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 --- net/sunrpc/rpcb_clnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index b23a719aca3..a70cc1e1179 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[] = { -- GitLab From 8842413aa4c3220ce9313791f99808fc149ca16d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:47 -0400 Subject: [PATCH 1324/2509] 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 --- net/sunrpc/rpcb_clnt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index a70cc1e1179..625ba72e624 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, -- GitLab From 40fef8a649e5344bfb6a67a7cc3def3e0dad6448 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:54 -0400 Subject: [PATCH 1325/2509] 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 --- fs/Kconfig | 21 --------------------- net/sunrpc/rpcb_clnt.c | 12 ------------ 2 files changed, 33 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index 1c16de9611e..0ce72dcd6b9 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 625ba72e624..c62e446723a 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, }, -- GitLab From 259875efed06d6936f54c9a264e868937f1bc217 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jul 2008 14:43:47 -0400 Subject: [PATCH 1326/2509] 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 --- fs/nfs/client.c | 13 +++++---- fs/nfs/super.c | 60 +++++++++++++++++++++++++++++------------- include/linux/nfs_fs.h | 5 ++++ 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index f2a092ca69b..5ee23e7058b 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 73a8e5970f0..9c1a960f5b9 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -816,6 +816,43 @@ static void nfs_parse_ip_address(char *string, size_t str_len, nfs_parse_ipv4_address(string, str_len, sap, addr_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 27d6a8d98ce..830d9cc8cdc 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) -- GitLab From ed596a8adb7964cf9d2f7682f9cf2c37322a775d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 26 Jun 2008 17:47:05 -0400 Subject: [PATCH 1327/2509] 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 --- fs/nfs/super.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 9c1a960f5b9..de424d2f315 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) { -- GitLab From 0e0cab744b17a70ef0f08d818d66935feade7cad Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 26 Jun 2008 17:47:12 -0400 Subject: [PATCH 1328/2509] NFS: use documenting macro constants for initializing ac{reg, dir}{min, max} Clean up. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/nfsroot.c | 8 ++++---- fs/nfs/super.c | 24 ++++++++++++------------ include/linux/nfs_fs.h | 5 +++++ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 15afe3a6c5b..46763d1cd39 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 de424d2f315..ebed63e0ff8 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 830d9cc8cdc..29d26191873 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: -- GitLab From 01060c896e3e1ef53dcb914301c186932cd31b81 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:38 -0400 Subject: [PATCH 1329/2509] 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 --- fs/nfs/super.c | 143 +++++++++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ebed63e0ff8..6eb145ea71a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -853,6 +853,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); -- GitLab From dd07c94750cb1ee4449fb0db06623e1865b3e26e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:46 -0400 Subject: [PATCH 1330/2509] 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 --- fs/nfs/super.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 6eb145ea71a..2f7e7f20c91 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; -- GitLab From 6738b2512bdf93ffbefe108b38a9165d5a718c3f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:54 -0400 Subject: [PATCH 1331/2509] 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 --- fs/nfs/super.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f7e7f20c91..4bbdbf6de41 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; -- GitLab From f45663ce5fb30f76a3414ab3ac69f4dd320e760a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 19:28:02 -0400 Subject: [PATCH 1332/2509] 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 --- fs/nfs/super.c | 203 +++++++++++++++++++++++++++++++------------------ 1 file changed, 128 insertions(+), 75 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 4bbdbf6de41..47cf83e917b 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; } /* -- GitLab From 381ba74af55e58bca4c01553835a360a9f6fbb07 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 7 Jul 2008 12:18:53 -0400 Subject: [PATCH 1333/2509] 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 --- net/sunrpc/clnt.c | 8 +++----- net/sunrpc/rpcb_clnt.c | 38 ++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 09631f6e30e..76739e928d0 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 c62e446723a..24e93e0a0a2 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, -- GitLab From 9fde9bdd3023854f7b03cc425ff4a0ed51bd1eb3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 9 Jul 2008 10:56:11 -0600 Subject: [PATCH 1334/2509] powerpc/440: Convert Virtex ML507 device tree to dts-v1 Signed-off-by: Grant Likely --- arch/powerpc/boot/dts/virtex440-ml507.dts | 256 +++++++++++++--------- 1 file changed, 157 insertions(+), 99 deletions(-) diff --git a/arch/powerpc/boot/dts/virtex440-ml507.dts b/arch/powerpc/boot/dts/virtex440-ml507.dts index f1b334454f5..dc8e78e2dce 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 >; } ; } ; -- GitLab From 1bc54c03117b90716e0dedd7abb2a20405de65df Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 8 Jul 2008 15:54:40 +1000 Subject: [PATCH 1335/2509] 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 --- arch/powerpc/kernel/head_44x.S | 286 ++++++++++------------------ arch/powerpc/kernel/head_booke.h | 8 + arch/powerpc/mm/44x_mmu.c | 29 ++- arch/powerpc/mm/fault.c | 3 +- include/asm-powerpc/pgtable-ppc32.h | 61 ++++-- 5 files changed, 180 insertions(+), 207 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 2944529e8bf..f3a1ea9d7fe 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 b0461be1c92..fce2df98850 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 953fb919eb0..98052ac9658 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 7b251079926..1707d00331f 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 e1d2bb57f1d..11eede4a290 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; \ -- GitLab From 4248652d4f3ce6be1a94c77ddbfeb937af1df800 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Wed, 9 Jul 2008 05:00:10 +1000 Subject: [PATCH 1336/2509] 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 --- arch/powerpc/platforms/44x/warp-nand.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c index 7bec2815771..e55746b824b 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); } -- GitLab From 3fa69dd57759cb45fa48bb70a055025d25a7e4e8 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 9 Jul 2008 14:05:15 -0400 Subject: [PATCH 1337/2509] powerpc/44x: Update ppc44x_defconfig Add the virtex and sam440ep platforms to the multiboard defconfig Signed-off-by: Josh Boyer --- arch/powerpc/configs/ppc44x_defconfig | 149 ++++++++++++++++++-------- 1 file changed, 104 insertions(+), 45 deletions(-) diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 12f9b5a8022..f9d279bb700 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 -- GitLab From 2bf3016f89344d4cd8b2c96bbec2b642a2bde413 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 10 Jul 2008 01:09:23 +1000 Subject: [PATCH 1338/2509] 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 --- arch/powerpc/mm/init_32.c | 4 ++-- arch/powerpc/mm/mem.c | 8 ++++---- arch/powerpc/mm/mmu_decl.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 45418590b6a..388ceda632f 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 776ba6ad5e1..1ca2235f096 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 46585b7bb19..fab3cfad409 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; -- GitLab From bdb08cb2d3491d441dd403dfb88d90ba90fb7232 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 30 Jun 2008 19:47:59 +0100 Subject: [PATCH 1339/2509] [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 --- arch/arm/mach-pxa/clock.c | 3 +++ arch/arm/mach-pxa/clock.h | 12 ++++++++++++ arch/arm/mach-pxa/pxa25x.c | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index e97dc59813c..68afc396b4a 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 bc6b77e1592..83cbfaba485 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 e5b417d14bb..09ee131d24a 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; } -- GitLab From 66a7f72d9892013e9ea663260f407758989ff510 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 2 Jun 2008 16:10:20 +0100 Subject: [PATCH 1340/2509] [ARM] pxa: remove pxa_set_cken() pxa_set_cken() is now unused, remove it. Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 18 ------------------ include/asm-arm/arch-pxa/hardware.h | 9 --------- 2 files changed, 27 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index c2f102339f5..ca053226fba 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" @@ -60,23 +59,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. * diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index e25558faa5a..d9af6dabc89 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -191,15 +191,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 */ -- GitLab From 330ff197fcdc83ba151960d78294fb37777ebe12 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:52:27 +0100 Subject: [PATCH 1341/2509] [ARM] 5144/1: pxaficp_ir: cleanup includes Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- drivers/net/irda/pxaficp_ir.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index d5c2d27f3ea..a19c00ad8b2 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) -- GitLab From 918dbcba4ee3f0ad7d617b3969d5016481b9ceff Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:53:45 +0100 Subject: [PATCH 1342/2509] [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 --- arch/arm/mach-pxa/Makefile | 4 +-- arch/arm/mach-pxa/pxa2xx.c | 46 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/irda.h | 4 +++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-pxa/pxa2xx.c diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 02cbc3cfbe0..c4dfbe87fc4 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 00000000000..d4f6415e841 --- /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 99f4f423a8e..0a50c3c763d 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 -- GitLab From 73d1a2c467ba4fb7420b499b6a7c66edf9626679 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:55:28 +0100 Subject: [PATCH 1343/2509] [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 --- drivers/net/irda/pxaficp_ir.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index a19c00ad8b2..f76b0b6c277 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); -- GitLab From 7a8576204333d133d58cbcc59dacf49a5546e3e4 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 22 Jun 2008 23:36:39 +0100 Subject: [PATCH 1344/2509] [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 --- arch/arm/mach-ixp4xx/common.c | 4 +- arch/arm/mach-pxa/devices.c | 15 +- arch/arm/mach-pxa/devices.h | 3 +- arch/arm/mach-pxa/pxa25x.c | 4 +- arch/arm/mach-pxa/pxa27x.c | 4 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- drivers/usb/gadget/Kconfig | 12 +- drivers/usb/gadget/Makefile | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/gadget_chips.h | 4 +- drivers/usb/gadget/inode.c | 2 +- .../usb/gadget/{pxa2xx_udc.c => pxa25x_udc.c} | 299 +++++++++--------- .../usb/gadget/{pxa2xx_udc.h => pxa25x_udc.h} | 29 +- drivers/usb/gadget/pxa27x_udc.c | 4 +- 14 files changed, 198 insertions(+), 188 deletions(-) rename drivers/usb/gadget/{pxa2xx_udc.c => pxa25x_udc.c} (89%) rename drivers/usb/gadget/{pxa2xx_udc.h => pxa25x_udc.h} (92%) diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index f6d66dce685..3781b3db9f4 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 4a1eebb42e4..123ee19ca79 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 e620a3373d4..881d1a7bf17 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 a1a7dd23ce5..4cd50e3005e 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 4d7afae352a..d5d14ea33f2 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 d26a9b02a55..15685d2b8f8 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 6e784d2db42..13dcec30457 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 12357255d74..e258afd25fa 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 8d61ea67a81..4ce3950b997 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 f7f159c1002..ca5149ea731 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 69b0a2754f2..f132a9219e1 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/pxa2xx_udc.c b/drivers/usb/gadget/pxa25x_udc.c similarity index 89% rename from drivers/usb/gadget/pxa2xx_udc.c rename to drivers/usb/gadget/pxa25x_udc.c index 63db96adc0b..031dceb9302 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1,5 +1,4 @@ /* - * 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) @@ -97,7 +96,7 @@ #define DRIVER_DESC "PXA 25x USB Device Controller driver" -static const char driver_name [] = "pxa2xx_udc"; +static const char driver_name [] = "pxa25x_udc"; static const char ep0name [] = "ep0"; @@ -117,10 +116,10 @@ static const char ep0name [] = "ep0"; #endif -#include "pxa2xx_udc.h" +#include "pxa25x_udc.h" -#ifdef CONFIG_USB_PXA2XX_SMALL +#ifdef CONFIG_USB_PXA25X_SMALL #define SIZE_STR " (small)" #else #define SIZE_STR "" @@ -132,8 +131,8 @@ static const char ep0name [] = "ep0"; * --------------------------------------------------------------------------- */ -static void pxa2xx_ep_fifo_flush (struct usb_ep *ep); -static void nuke (struct pxa2xx_ep *, int status); +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) @@ -218,24 +217,24 @@ static inline void udc_ack_int_UDCCR(int mask) /* * endpoint enable/disable * - * we need to verify the descriptors used to enable endpoints. since pxa2xx + * 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 pxa2xx can't selectively initialize bulk (or interrupt) endpoints, + * 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 pxa2xx_ep_enable (struct usb_ep *_ep, +static int pxa25x_ep_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) { - struct pxa2xx_ep *ep; - struct pxa2xx_udc *dev; + struct pxa25x_ep *ep; + struct pxa25x_udc *dev; - ep = container_of (_ep, struct pxa2xx_ep, ep); + 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 @@ -274,7 +273,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); /* flush fifo (mostly for OUT buffers) */ - pxa2xx_ep_fifo_flush (_ep); + pxa25x_ep_fifo_flush (_ep); /* ... reset halt state too, if we could ... */ @@ -282,12 +281,12 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, return 0; } -static int pxa2xx_ep_disable (struct usb_ep *_ep) +static int pxa25x_ep_disable (struct usb_ep *_ep) { - struct pxa2xx_ep *ep; + struct pxa25x_ep *ep; unsigned long flags; - ep = container_of (_ep, struct pxa2xx_ep, ep); + ep = container_of (_ep, struct pxa25x_ep, ep); if (!_ep || !ep->desc) { DMSG("%s, %s not enabled\n", __func__, _ep ? ep->ep.name : NULL); @@ -298,7 +297,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) nuke (ep, -ESHUTDOWN); /* flush fifo (mostly for IN buffers) */ - pxa2xx_ep_fifo_flush (_ep); + pxa25x_ep_fifo_flush (_ep); ep->desc = NULL; ep->stopped = 1; @@ -310,18 +309,18 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) /*-------------------------------------------------------------------------*/ -/* for the pxa2xx, these can just wrap kmalloc/kfree. gadget drivers +/* 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). */ /* - * pxa2xx_ep_alloc_request - allocate a request data structure + * pxa25x_ep_alloc_request - allocate a request data structure */ static struct usb_request * -pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) +pxa25x_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) { - struct pxa2xx_request *req; + struct pxa25x_request *req; req = kzalloc(sizeof(*req), gfp_flags); if (!req) @@ -333,14 +332,14 @@ pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) /* - * pxa2xx_ep_free_request - deallocate a request data structure + * pxa25x_ep_free_request - deallocate a request data structure */ static void -pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) +pxa25x_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) { - struct pxa2xx_request *req; + struct pxa25x_request *req; - req = container_of (_req, struct pxa2xx_request, req); + req = container_of (_req, struct pxa25x_request, req); WARN_ON (!list_empty (&req->queue)); kfree(req); } @@ -350,7 +349,7 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) /* * done - retire a request; caller blocked irqs */ -static void done(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int status) +static void done(struct pxa25x_ep *ep, struct pxa25x_request *req, int status) { unsigned stopped = ep->stopped; @@ -373,13 +372,13 @@ static void done(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int status) } -static inline void ep0_idle (struct pxa2xx_udc *dev) +static inline void ep0_idle (struct pxa25x_udc *dev) { dev->ep0state = EP0_IDLE; } static int -write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max) +write_packet(volatile u32 *uddr, struct pxa25x_request *req, unsigned max) { u8 *buf; unsigned length, count; @@ -404,7 +403,7 @@ write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max) * caller guarantees at least one packet buffer is ready (or a zlp). */ static int -write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) +write_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) { unsigned max; @@ -461,7 +460,7 @@ write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) * ep0 data stage. these chips want very simple state transitions. */ static inline -void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag) +void ep0start(struct pxa25x_udc *dev, u32 flags, const char *tag) { UDCCS0 = flags|UDCCS0_SA|UDCCS0_OPR; USIR0 = USIR0_IR0; @@ -471,7 +470,7 @@ void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag) } static int -write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) +write_ep0_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) { unsigned count; int is_short; @@ -531,7 +530,7 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) * request buffer having filled (and maybe overran till end-of-packet). */ static int -read_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) +read_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) { for (;;) { u32 udccs; @@ -608,7 +607,7 @@ read_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) * protocols do use them. */ static int -read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) +read_ep0_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) { u8 *buf, byte; unsigned bufferspace; @@ -647,21 +646,21 @@ read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) /*-------------------------------------------------------------------------*/ static int -pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) +pxa25x_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; + struct pxa25x_request *req; + struct pxa25x_ep *ep; + struct pxa25x_udc *dev; unsigned long flags; - req = container_of(_req, struct pxa2xx_request, req); + 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 pxa2xx_ep, ep); + 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; @@ -757,14 +756,14 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* * nuke - dequeue ALL requests */ -static void nuke(struct pxa2xx_ep *ep, int status) +static void nuke(struct pxa25x_ep *ep, int status) { - struct pxa2xx_request *req; + struct pxa25x_request *req; /* called with irqs blocked */ while (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, - struct pxa2xx_request, + struct pxa25x_request, queue); done(ep, req, status); } @@ -774,13 +773,13 @@ static void nuke(struct pxa2xx_ep *ep, int status) /* dequeue JUST ONE request */ -static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +static int pxa25x_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) { - struct pxa2xx_ep *ep; - struct pxa2xx_request *req; + struct pxa25x_ep *ep; + struct pxa25x_request *req; unsigned long flags; - ep = container_of(_ep, struct pxa2xx_ep, ep); + ep = container_of(_ep, struct pxa25x_ep, ep); if (!_ep || ep->ep.name == ep0name) return -EINVAL; @@ -804,12 +803,12 @@ static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) /*-------------------------------------------------------------------------*/ -static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value) +static int pxa25x_ep_set_halt(struct usb_ep *_ep, int value) { - struct pxa2xx_ep *ep; + struct pxa25x_ep *ep; unsigned long flags; - ep = container_of(_ep, struct pxa2xx_ep, ep); + ep = container_of(_ep, struct pxa25x_ep, ep); if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name)) || ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { @@ -859,11 +858,11 @@ static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value) return 0; } -static int pxa2xx_ep_fifo_status(struct usb_ep *_ep) +static int pxa25x_ep_fifo_status(struct usb_ep *_ep) { - struct pxa2xx_ep *ep; + struct pxa25x_ep *ep; - ep = container_of(_ep, struct pxa2xx_ep, ep); + ep = container_of(_ep, struct pxa25x_ep, ep); if (!_ep) { DMSG("%s, bad ep\n", __func__); return -ENODEV; @@ -878,11 +877,11 @@ static int pxa2xx_ep_fifo_status(struct usb_ep *_ep) return (*ep->reg_ubcr & 0xfff) + 1; } -static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep) +static void pxa25x_ep_fifo_flush(struct usb_ep *_ep) { - struct pxa2xx_ep *ep; + struct pxa25x_ep *ep; - ep = container_of(_ep, struct pxa2xx_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; @@ -904,19 +903,19 @@ static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep) } -static struct usb_ep_ops pxa2xx_ep_ops = { - .enable = pxa2xx_ep_enable, - .disable = pxa2xx_ep_disable, +static struct usb_ep_ops pxa25x_ep_ops = { + .enable = pxa25x_ep_enable, + .disable = pxa25x_ep_disable, - .alloc_request = pxa2xx_ep_alloc_request, - .free_request = pxa2xx_ep_free_request, + .alloc_request = pxa25x_ep_alloc_request, + .free_request = pxa25x_ep_free_request, - .queue = pxa2xx_ep_queue, - .dequeue = pxa2xx_ep_dequeue, + .queue = pxa25x_ep_queue, + .dequeue = pxa25x_ep_dequeue, - .set_halt = pxa2xx_ep_set_halt, - .fifo_status = pxa2xx_ep_fifo_status, - .fifo_flush = pxa2xx_ep_fifo_flush, + .set_halt = pxa25x_ep_set_halt, + .fifo_status = pxa25x_ep_fifo_status, + .fifo_flush = pxa25x_ep_fifo_flush, }; @@ -925,12 +924,12 @@ static struct usb_ep_ops pxa2xx_ep_ops = { * --------------------------------------------------------------------------- */ -static int pxa2xx_udc_get_frame(struct usb_gadget *_gadget) +static int pxa25x_udc_get_frame(struct usb_gadget *_gadget) { return ((UFNRH & 0x07) << 8) | (UFNRL & 0xff); } -static int pxa2xx_udc_wakeup(struct usb_gadget *_gadget) +static int pxa25x_udc_wakeup(struct usb_gadget *_gadget) { /* host may not have enabled remote wakeup */ if ((UDCCS0 & UDCCS0_DRWF) == 0) @@ -939,14 +938,14 @@ static int pxa2xx_udc_wakeup(struct usb_gadget *_gadget) 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 *); +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 pxa2xx_udc *udc) +static int pullup(struct pxa25x_udc *udc) { int is_active = udc->vbus && udc->pullup && !udc->suspended; DMSG("%s\n", is_active ? "active" : "inactive"); @@ -976,11 +975,11 @@ static int pullup(struct pxa2xx_udc *udc) } /* VBUS reporting logically comes from a transceiver */ -static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) +static int pxa25x_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { - struct pxa2xx_udc *udc; + struct pxa25x_udc *udc; - udc = container_of(_gadget, struct pxa2xx_udc, gadget); + udc = container_of(_gadget, struct pxa25x_udc, gadget); udc->vbus = (is_active != 0); DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); pullup(udc); @@ -988,11 +987,11 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) } /* drivers may have software control over D+ pullup */ -static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) +static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) { - struct pxa2xx_udc *udc; + struct pxa25x_udc *udc; - udc = container_of(_gadget, struct pxa2xx_udc, gadget); + udc = container_of(_gadget, struct pxa25x_udc, gadget); /* not all boards support pullup control */ if (!udc->mach->gpio_pullup && !udc->mach->udc_command) @@ -1003,11 +1002,11 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) 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, +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 @@ -1021,7 +1020,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { static int udc_seq_show(struct seq_file *m, void *_d) { - struct pxa2xx_udc *dev = m->private; + struct pxa25x_udc *dev = m->private; unsigned long flags; int i; u32 tmp; @@ -1082,8 +1081,8 @@ udc_seq_show(struct seq_file *m, void *_d) /* dump endpoint queues */ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep [i]; - struct pxa2xx_request *req; + struct pxa25x_ep *ep = &dev->ep [i]; + struct pxa25x_request *req; if (i != 0) { const struct usb_endpoint_descriptor *desc; @@ -1156,7 +1155,7 @@ static const struct file_operations debug_fops = { /* * udc_disable - disable USB device controller */ -static void udc_disable(struct pxa2xx_udc *dev) +static void udc_disable(struct pxa25x_udc *dev) { /* block all irqs */ udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM); @@ -1176,7 +1175,7 @@ static void udc_disable(struct pxa2xx_udc *dev) /* * udc_reinit - initialize software state */ -static void udc_reinit(struct pxa2xx_udc *dev) +static void udc_reinit(struct pxa25x_udc *dev) { u32 i; @@ -1187,7 +1186,7 @@ static void udc_reinit(struct pxa2xx_udc *dev) /* basic endpoint records init */ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep[i]; + struct pxa25x_ep *ep = &dev->ep[i]; if (i != 0) list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); @@ -1204,7 +1203,7 @@ static void udc_reinit(struct pxa2xx_udc *dev) /* until it's enabled, this UDC should be completely invisible * to any USB host. */ -static void udc_enable (struct pxa2xx_udc *dev) +static void udc_enable (struct pxa25x_udc *dev) { udc_clear_mask_UDCCR(UDCCR_UDE); @@ -1260,7 +1259,7 @@ static void udc_enable (struct pxa2xx_udc *dev) */ int usb_gadget_register_driver(struct usb_gadget_driver *driver) { - struct pxa2xx_udc *dev = the_controller; + struct pxa25x_udc *dev = the_controller; int retval; if (!driver @@ -1305,7 +1304,7 @@ fail: EXPORT_SYMBOL(usb_gadget_register_driver); static void -stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver) +stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) { int i; @@ -1316,7 +1315,7 @@ stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver) /* prevent new request submissions, kill any outstanding requests */ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep[i]; + struct pxa25x_ep *ep = &dev->ep[i]; ep->stopped = 1; nuke(ep, -ESHUTDOWN); @@ -1333,7 +1332,7 @@ stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver) int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { - struct pxa2xx_udc *dev = the_controller; + struct pxa25x_udc *dev = the_controller; if (!dev) return -ENODEV; @@ -1370,7 +1369,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); static irqreturn_t lubbock_vbus_irq(int irq, void *_dev) { - struct pxa2xx_udc *dev = _dev; + struct pxa25x_udc *dev = _dev; int vbus; dev->stats.irqs++; @@ -1389,7 +1388,7 @@ lubbock_vbus_irq(int irq, void *_dev) return IRQ_NONE; } - pxa2xx_udc_vbus_session(&dev->gadget, vbus); + pxa25x_udc_vbus_session(&dev->gadget, vbus); return IRQ_HANDLED; } @@ -1397,20 +1396,20 @@ lubbock_vbus_irq(int irq, void *_dev) static irqreturn_t udc_vbus_irq(int irq, void *_dev) { - struct pxa2xx_udc *dev = _dev; + struct pxa25x_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); + pxa25x_udc_vbus_session(&dev->gadget, vbus); return IRQ_HANDLED; } /*-------------------------------------------------------------------------*/ -static inline void clear_ep_state (struct pxa2xx_udc *dev) +static inline void clear_ep_state (struct pxa25x_udc *dev) { unsigned i; @@ -1423,7 +1422,7 @@ static inline void clear_ep_state (struct pxa2xx_udc *dev) static void udc_watchdog(unsigned long _dev) { - struct pxa2xx_udc *dev = (void *)_dev; + struct pxa25x_udc *dev = (void *)_dev; local_irq_disable(); if (dev->ep0state == EP0_STALL @@ -1436,11 +1435,11 @@ static void udc_watchdog(unsigned long _dev) local_irq_enable(); } -static void handle_ep0 (struct pxa2xx_udc *dev) +static void handle_ep0 (struct pxa25x_udc *dev) { u32 udccs0 = UDCCS0; - struct pxa2xx_ep *ep = &dev->ep [0]; - struct pxa2xx_request *req; + struct pxa25x_ep *ep = &dev->ep [0]; + struct pxa25x_request *req; union { struct usb_ctrlrequest r; u8 raw [8]; @@ -1450,7 +1449,7 @@ static void handle_ep0 (struct pxa2xx_udc *dev) if (list_empty(&ep->queue)) req = NULL; else - req = list_entry(ep->queue.next, struct pxa2xx_request, queue); + req = list_entry(ep->queue.next, struct pxa25x_request, queue); /* clear stall status */ if (udccs0 & UDCCS0_SST) { @@ -1660,9 +1659,9 @@ stall: USIR0 = USIR0_IR0; } -static void handle_ep(struct pxa2xx_ep *ep) +static void handle_ep(struct pxa25x_ep *ep) { - struct pxa2xx_request *req; + struct pxa25x_request *req; int is_in = ep->bEndpointAddress & USB_DIR_IN; int completed; u32 udccs, tmp; @@ -1671,7 +1670,7 @@ static void handle_ep(struct pxa2xx_ep *ep) completed = 0; if (likely (!list_empty(&ep->queue))) req = list_entry(ep->queue.next, - struct pxa2xx_request, queue); + struct pxa25x_request, queue); else req = NULL; @@ -1708,16 +1707,16 @@ static void handle_ep(struct pxa2xx_ep *ep) } /* - * pxa2xx_udc_irq - interrupt handler + * 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 -pxa2xx_udc_irq(int irq, void *_dev) +pxa25x_udc_irq(int irq, void *_dev) { - struct pxa2xx_udc *dev = _dev; + struct pxa25x_udc *dev = _dev; int handled; dev->stats.irqs++; @@ -1826,9 +1825,9 @@ static void nop_release (struct device *dev) * doing it at run-time) to save code, eliminate fault paths, and * be more obviously correct. */ -static struct pxa2xx_udc memory = { +static struct pxa25x_udc memory = { .gadget = { - .ops = &pxa2xx_udc_ops, + .ops = &pxa25x_udc_ops, .ep0 = &memory.ep[0].ep, .name = driver_name, .dev = { @@ -1841,7 +1840,7 @@ static struct pxa2xx_udc memory = { .ep[0] = { .ep = { .name = ep0name, - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = EP0_FIFO_SIZE, }, .dev = &memory, @@ -1853,7 +1852,7 @@ static struct pxa2xx_udc memory = { .ep[1] = { .ep = { .name = "ep1in-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -1866,7 +1865,7 @@ static struct pxa2xx_udc memory = { .ep[2] = { .ep = { .name = "ep2out-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -1877,11 +1876,11 @@ static struct pxa2xx_udc memory = { .reg_ubcr = &UBCR2, .reg_uddr = &UDDR2, }, -#ifndef CONFIG_USB_PXA2XX_SMALL +#ifndef CONFIG_USB_PXA25X_SMALL .ep[3] = { .ep = { .name = "ep3in-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -1894,7 +1893,7 @@ static struct pxa2xx_udc memory = { .ep[4] = { .ep = { .name = "ep4out-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -1908,7 +1907,7 @@ static struct pxa2xx_udc memory = { .ep[5] = { .ep = { .name = "ep5in-int", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = INT_FIFO_SIZE, }, .dev = &memory, @@ -1923,7 +1922,7 @@ static struct pxa2xx_udc memory = { .ep[6] = { .ep = { .name = "ep6in-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -1936,7 +1935,7 @@ static struct pxa2xx_udc memory = { .ep[7] = { .ep = { .name = "ep7out-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -1950,7 +1949,7 @@ static struct pxa2xx_udc memory = { .ep[8] = { .ep = { .name = "ep8in-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -1963,7 +1962,7 @@ static struct pxa2xx_udc memory = { .ep[9] = { .ep = { .name = "ep9out-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -1977,7 +1976,7 @@ static struct pxa2xx_udc memory = { .ep[10] = { .ep = { .name = "ep10in-int", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = INT_FIFO_SIZE, }, .dev = &memory, @@ -1992,7 +1991,7 @@ static struct pxa2xx_udc memory = { .ep[11] = { .ep = { .name = "ep11in-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -2005,7 +2004,7 @@ static struct pxa2xx_udc memory = { .ep[12] = { .ep = { .name = "ep12out-bulk", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = BULK_FIFO_SIZE, }, .dev = &memory, @@ -2019,7 +2018,7 @@ static struct pxa2xx_udc memory = { .ep[13] = { .ep = { .name = "ep13in-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -2032,7 +2031,7 @@ static struct pxa2xx_udc memory = { .ep[14] = { .ep = { .name = "ep14out-iso", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = ISO_FIFO_SIZE, }, .dev = &memory, @@ -2046,7 +2045,7 @@ static struct pxa2xx_udc memory = { .ep[15] = { .ep = { .name = "ep15in-int", - .ops = &pxa2xx_ep_ops, + .ops = &pxa25x_ep_ops, .maxpacket = INT_FIFO_SIZE, }, .dev = &memory, @@ -2056,7 +2055,7 @@ static struct pxa2xx_udc memory = { .reg_udccs = &UDCCS15, .reg_uddr = &UDDR15, }, -#endif /* !CONFIG_USB_PXA2XX_SMALL */ +#endif /* !CONFIG_USB_PXA25X_SMALL */ }; #define CP15R0_VENDOR_MASK 0xffffe000 @@ -2096,9 +2095,9 @@ static struct pxa2xx_udc memory = { /* * probe - binds to the platform device */ -static int __init pxa2xx_udc_probe(struct platform_device *pdev) +static int __init pxa25x_udc_probe(struct platform_device *pdev) { - struct pxa2xx_udc *dev = &memory; + struct pxa25x_udc *dev = &memory; int retval, vbus_irq, irq; u32 chiprev; @@ -2161,7 +2160,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) if (dev->mach->gpio_vbus) { if ((retval = gpio_request(dev->mach->gpio_vbus, - "pxa2xx_udc GPIO VBUS"))) { + "pxa25x_udc GPIO VBUS"))) { dev_dbg(&pdev->dev, "can't get vbus gpio %d, err: %d\n", dev->mach->gpio_vbus, retval); @@ -2174,7 +2173,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) if (dev->mach->gpio_pullup) { if ((retval = gpio_request(dev->mach->gpio_pullup, - "pca2xx_udc GPIO PULLUP"))) { + "pca25x_udc GPIO PULLUP"))) { dev_dbg(&pdev->dev, "can't get pullup gpio %d, err: %d\n", dev->mach->gpio_pullup, retval); @@ -2200,7 +2199,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) dev->vbus = is_vbus_present(); /* irq setup after old hardware state is cleaned up */ - retval = request_irq(irq, pxa2xx_udc_irq, + 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", @@ -2266,14 +2265,14 @@ lubbock_fail0: return retval; } -static void pxa2xx_udc_shutdown(struct platform_device *_dev) +static void pxa25x_udc_shutdown(struct platform_device *_dev) { pullup_off(); } -static int __exit pxa2xx_udc_remove(struct platform_device *pdev) +static int __exit pxa25x_udc_remove(struct platform_device *pdev) { - struct pxa2xx_udc *dev = platform_get_drvdata(pdev); + struct pxa25x_udc *dev = platform_get_drvdata(pdev); if (dev->driver) return -EBUSY; @@ -2323,9 +2322,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) * 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) +static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) { - struct pxa2xx_udc *udc = platform_get_drvdata(dev); + struct pxa25x_udc *udc = platform_get_drvdata(dev); unsigned long flags; if (!udc->mach->gpio_pullup && !udc->mach->udc_command) @@ -2339,9 +2338,9 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) return 0; } -static int pxa2xx_udc_resume(struct platform_device *dev) +static int pxa25x_udc_resume(struct platform_device *dev) { - struct pxa2xx_udc *udc = platform_get_drvdata(dev); + struct pxa25x_udc *udc = platform_get_drvdata(dev); unsigned long flags; udc->suspended = 0; @@ -2353,27 +2352,27 @@ static int pxa2xx_udc_resume(struct platform_device *dev) } #else -#define pxa2xx_udc_suspend NULL -#define pxa2xx_udc_resume NULL +#define pxa25x_udc_suspend NULL +#define pxa25x_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, + .shutdown = pxa25x_udc_shutdown, + .remove = __exit_p(pxa25x_udc_remove), + .suspend = pxa25x_udc_suspend, + .resume = pxa25x_udc_resume, .driver = { .owner = THIS_MODULE, - .name = "pxa2xx-udc", + .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, pxa2xx_udc_probe); + return platform_driver_probe(&udc_driver, pxa25x_udc_probe); } module_init(udc_init); @@ -2386,4 +2385,4 @@ module_exit(udc_exit); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pxa2xx-udc"); +MODULE_ALIAS("platform:pxa25x-udc"); diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa25x_udc.h similarity index 92% rename from drivers/usb/gadget/pxa2xx_udc.h rename to drivers/usb/gadget/pxa25x_udc.h index e2c19e88c87..4d11ece7c95 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa25x_udc.h @@ -1,6 +1,5 @@ /* - * linux/drivers/usb/gadget/pxa2xx_udc.h - * Intel PXA2xx on-chip full speed USB device controller + * Intel PXA25x on-chip full speed USB device controller * * Copyright (C) 2003 Robert Schwebel , Pengutronix * Copyright (C) 2003 David Brownell @@ -21,14 +20,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __LINUX_USB_GADGET_PXA2XX_H -#define __LINUX_USB_GADGET_PXA2XX_H +#ifndef __LINUX_USB_GADGET_PXA25X_H +#define __LINUX_USB_GADGET_PXA25X_H #include /*-------------------------------------------------------------------------*/ -/* pxa2xx has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */ +/* 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 */ @@ -45,11 +44,11 @@ /*-------------------------------------------------------------------------*/ -struct pxa2xx_udc; +struct pxa25x_udc; -struct pxa2xx_ep { +struct pxa25x_ep { struct usb_ep ep; - struct pxa2xx_udc *dev; + struct pxa25x_udc *dev; const struct usb_endpoint_descriptor *desc; struct list_head queue; @@ -72,7 +71,7 @@ struct pxa2xx_ep { volatile u32 *reg_uddr; }; -struct pxa2xx_request { +struct pxa25x_request { struct usb_request req; struct list_head queue; }; @@ -98,7 +97,7 @@ struct udc_stats { unsigned long irqs; }; -#ifdef CONFIG_USB_PXA2XX_SMALL +#ifdef CONFIG_USB_PXA25X_SMALL /* when memory's tight, SMALL config saves code+data. */ #define PXA_UDC_NUM_ENDPOINTS 3 #endif @@ -107,7 +106,7 @@ struct udc_stats { #define PXA_UDC_NUM_ENDPOINTS 16 #endif -struct pxa2xx_udc { +struct pxa25x_udc { struct usb_gadget gadget; struct usb_gadget_driver *driver; @@ -130,7 +129,7 @@ struct pxa2xx_udc { struct clk *clk; struct pxa2xx_udc_mach_info *mach; u64 dma_mask; - struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; + struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS]; #ifdef CONFIG_USB_GADGET_DEBUG_FS struct dentry *debugfs_udc; @@ -144,7 +143,7 @@ struct pxa2xx_udc { /* lubbock can also report usb connect/disconnect irqs */ #endif -static struct pxa2xx_udc *the_controller; +static struct pxa25x_udc *the_controller; /*-------------------------------------------------------------------------*/ @@ -209,7 +208,7 @@ dump_udccs0(const char *label) } static void __maybe_unused -dump_state(struct pxa2xx_udc *dev) +dump_state(struct pxa25x_udc *dev) { u32 tmp; unsigned i; @@ -264,4 +263,4 @@ dump_state(struct pxa2xx_udc *dev) #define INFO(stuff...) pr_info("udc: " stuff) -#endif /* __LINUX_USB_GADGET_PXA2XX_H */ +#endif /* __LINUX_USB_GADGET_PXA25X_H */ diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 40d6b580f15..4771b1314d5 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), -- GitLab From 9f19d6382854d6b2d58cc364253779479e14facc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jun 2008 12:30:05 +0100 Subject: [PATCH 1345/2509] [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 --- arch/arm/mach-pxa/cm-x270.c | 9 ++------ arch/arm/mach-pxa/devices.c | 32 ++++++++++++++++++++++++++ arch/arm/mach-pxa/devices.h | 1 + arch/arm/mach-pxa/em-x270.c | 9 ++------ arch/arm/mach-pxa/lpd270.c | 8 ++----- arch/arm/mach-pxa/lubbock.c | 8 ++----- arch/arm/mach-pxa/mainstone.c | 8 +------ arch/arm/mach-pxa/pcm990-baseboard.c | 34 ++-------------------------- arch/arm/mach-pxa/trizeps4.c | 10 +------- include/asm-arm/arch-pxa/audio.h | 2 ++ 10 files changed, 47 insertions(+), 74 deletions(-) diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 6d4416a4f37..b3c3fd72d04 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 123ee19ca79..a6f2390ce66 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 881d1a7bf17..b852eb18daa 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 1269ac99150..e23865affc0 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 183b587672a..cc1c4fa0614 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 7b9bdd0c666..a3fae413920 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 266594426e8..f2e9e7c4da8 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 2564e16e4e2..5d87c7c866e 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 @@ -423,36 +424,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 */ @@ -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 bc7c465ef32..61e24402308 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 52bbe3bc25e..f82f96dd105 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 -- GitLab From cabb352a6455c3550f157909196845f533b0f374 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jun 2008 10:48:25 +0100 Subject: [PATCH 1346/2509] [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 --- arch/arm/mach-pxa/zylonite.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index b13bb938513..66b446ca273 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(); -- GitLab From 16074b669ea97e2bef494ec7cceb475566f763e3 Mon Sep 17 00:00:00 2001 From: Patrice Vilchez Date: Wed, 9 Jul 2008 22:16:00 +0100 Subject: [PATCH 1347/2509] [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 --- arch/arm/mach-at91/at91sam9260_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9261_devices.c | 12 ++++++------ arch/arm/mach-at91/at91sam9263_devices.c | 4 ++-- arch/arm/mach-at91/at91sam9rl_devices.c | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 393a32aefce..26f5cacbec3 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 0babb645b83..ec1891375df 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 719667e25c9..8a81f76f020 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 8507dd02fe9..ae28101e754 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) -- GitLab From 63f385cd1f649b3f4f2d59fc609e051981215fd7 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Tue, 8 Jul 2008 23:07:48 +0100 Subject: [PATCH 1348/2509] [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 --- arch/arm/Kconfig | 4 ++ arch/arm/plat-iop/gpio.c | 43 +++++++++++++++ include/asm-arm/arch-iop32x/gpio.h | 6 +++ include/asm-arm/arch-iop33x/gpio.h | 6 +++ include/asm-arm/hardware/iop3xx-gpio.h | 73 ++++++++++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 include/asm-arm/arch-iop32x/gpio.h create mode 100644 include/asm-arm/arch-iop33x/gpio.h create mode 100644 include/asm-arm/hardware/iop3xx-gpio.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..63ef7cf852a 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 eda43608341..640e498c12e 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 00000000000..708f4ec9db1 --- /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 00000000000..ddd55bba9bb --- /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 00000000000..0c9331f9ac2 --- /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 + -- GitLab From 48627d8d23c34106c1365563604739a50343edaf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Jul 2008 07:01:13 +0200 Subject: [PATCH 1349/2509] 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 --- kernel/irq/manage.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 469814e9b9e..77a51be3601 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); -- GitLab From 6b148507d3d042a3c11f4c3f6c0f649c6a89220d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 21 May 2008 21:14:58 +0200 Subject: [PATCH 1350/2509] 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 --- drivers/clocksource/acpi_pm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 7b46faf2231..3baee020afc 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); -- GitLab From 942fd1ebf6072fdaa07ae6d77a4f58b39c1bfdf9 Mon Sep 17 00:00:00 2001 From: Walter Sheets Date: Fri, 27 Jun 2008 11:53:31 +0200 Subject: [PATCH 1351/2509] 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 --- sound/pci/via82xx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index b585cc3e4c4..6781be9e307 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1756,6 +1756,12 @@ static struct ac97_quirk ac97_quirks[] = { .name = "ECS L7VMM2", .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x1019, + .subdevice = 0x1841, + .name = "ECS K7VTA3", + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x1849, .subdevice = 0x3059, -- GitLab From 6cabf6b0694951288520512e0b68c78523acc9fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jun 2008 11:55:20 +0200 Subject: [PATCH 1352/2509] 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 --- sound/pci/ac97/ac97_codec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 2d2f16e1108..07364c00768 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 */ -- GitLab From 4d20f70a787e03530786152ea27a6ed157205cdc Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 27 Jun 2008 14:07:57 +0300 Subject: [PATCH 1353/2509] 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 --- sound/soc/codecs/tlv320aic3x.c | 6 ++++++ sound/soc/codecs/tlv320aic3x.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 4f0bf26f170..d13830623db 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 c1dd1ac0cea..e6009461063 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 -- GitLab From 0701e0640f4a1de2b509cfee508216275f81d812 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jun 2008 16:30:57 +0200 Subject: [PATCH 1354/2509] 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 --- sound/pci/hda/patch_realtek.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7d4bbb0179..081d1a55706 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), -- GitLab From 470eaf6be78424fc499a5039e5d5fe58bace2bc3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jun 2008 16:40:10 +0200 Subject: [PATCH 1355/2509] 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 --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 05ca027fcc0..e8003d99f0b 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), -- GitLab From 6a9dccd61253f361760802d8d19c28fa83ea83f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Jul 2008 14:52:05 +0200 Subject: [PATCH 1356/2509] 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 --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 64df8100593..95e3367d887 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), -- GitLab From 25552e87aa4102f048f1a8a8ddc87c96593c304e Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 2 Jul 2008 13:19:23 +0300 Subject: [PATCH 1357/2509] 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 --- sound/pci/ac97/ac97_patch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index abe88adec37..0746e9ccc20 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; } -- GitLab From 5415552d21150dbfbff012de2b59e685ea232b1e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Jul 2008 11:51:19 +0100 Subject: [PATCH 1358/2509] ALSA: ASoC: Advertise 16000Hz rate for WM9713 PCM interface Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/codecs/wm9713.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 0db96374736..a4806189044 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, -- GitLab From 15e4c72f520d1db9adc38ba157547a7c1fca45b2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Jul 2008 11:51:20 +0100 Subject: [PATCH 1359/2509] 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 --- sound/soc/soc-dapm.c | 67 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 25363829e60..7c2dd4ec8df 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 */ -- GitLab From 3f775987030cf7ff922765c18ddd0d311b4b46ef Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 3 Jul 2008 09:33:10 +0200 Subject: [PATCH 1360/2509] 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 --- sound/soc/codecs/ac97.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 300d007f233..e4516f3ce64 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); -- GitLab From 73ead4855d98e330f2840523e1648575b9f2aae9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Jul 2008 16:01:14 +0100 Subject: [PATCH 1361/2509] ALSA: ASoC: Fix warning from strict_strtoul() Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/soc-dapm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7c2dd4ec8df..91cbbefefb0 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; -- GitLab From be321a890c25272965129ffe4b3b59a519fcf583 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 7 Jul 2008 16:04:04 +0200 Subject: [PATCH 1362/2509] 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 --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 081d1a55706..92a709be3c4 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), {} }; -- GitLab From a5302181e5321664047f75715242aac4e0bbd17c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 13:35:17 +0100 Subject: [PATCH 1363/2509] 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 --- include/sound/soc-dapm.h | 15 ++-- sound/soc/at91/eti_b1_wm8731.c | 10 +-- sound/soc/codecs/tlv320aic3x.c | 4 +- sound/soc/davinci/davinci-evm.c | 16 ++-- sound/soc/omap/n810.c | 27 +++++-- sound/soc/pxa/corgi.c | 42 ++++++----- sound/soc/pxa/poodle.c | 24 +++--- sound/soc/pxa/spitz.c | 62 +++++++-------- sound/soc/pxa/tosa.c | 30 ++++---- sound/soc/s3c24xx/neo1973_wm8753.c | 116 ++++++++++++++--------------- sound/soc/sh/sh7760-ac97.c | 2 +- sound/soc/soc-dapm.c | 81 ++++++++++++-------- 12 files changed, 230 insertions(+), 199 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index b2849538cbf..3030fdc6981 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 4a383a4a0ff..ad971e7061f 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 d13830623db..954d39b7c04 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 4c70a0ed339..091eae3a963 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 767b39f339a..74f4599b4d7 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 edeea63e80e..db18ef68b69 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 810f1fe158a..36cbf69f5f8 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 092b5c776b4..ec18163fddd 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 465ff0f458e..dba7689c508 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 34851238dea..f053e85ff60 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 2f91de84c5c..846d1b3a630 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 91cbbefefb0..94296b5dc58 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 -- GitLab From 3c4b266fe642bcaebe2b95edb56c3f8802924ff9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:17 +0100 Subject: [PATCH 1364/2509] 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 --- include/sound/soc.h | 71 ++++++++++++++------------------------------ sound/soc/soc-core.c | 50 +++++++++++++++---------------- 2 files changed, 48 insertions(+), 73 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 340223a8f24..778e57e74dc 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 bdbbc6a980f..4d626b47b2f 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 -- GitLab From 453ba20b2800bc07a3eaf220010dc0127cc552fd Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:29 +0100 Subject: [PATCH 1365/2509] 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 --- sound/soc/at32/at32-pcm.c | 6 +++--- sound/soc/at32/at32-ssc.c | 12 ++++++------ sound/soc/at32/at32-ssc.h | 2 +- sound/soc/at32/playpaq_wm8510.c | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c index cf76e89fae6..435f1daf177 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 0ca44107f18..4ef6492c902 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 3c6901a6c03..3c052dbbe46 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 d6b9fd5e612..18ac7d7391c 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; -- GitLab From d37ae539a1d76da8fe5a939ce8b6d818501c8716 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:37 +0100 Subject: [PATCH 1366/2509] 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 --- sound/soc/at91/at91-pcm.c | 6 +++--- sound/soc/at91/at91-ssc.c | 12 ++++++------ sound/soc/at91/at91-ssc.h | 2 +- sound/soc/at91/eti_b1_wm8731.c | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c index ccac6bd2889..d47492b2b6e 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 bc35d00a38f..c3625b665c5 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 b188f973df9..6b7bf382d06 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 ad971e7061f..9d4213963c2 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 -- GitLab From 9cb132d743cf39b3bbe4288e9035217e7237a0bb Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:42 +0100 Subject: [PATCH 1367/2509] 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 --- sound/soc/davinci/davinci-evm.c | 4 ++-- sound/soc/davinci/davinci-i2s.c | 14 +++++++------- sound/soc/davinci/davinci-i2s.h | 2 +- sound/soc/davinci/davinci-pcm.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 091eae3a963..4249e6a8574 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 c3b545ccff7..5ebf1ff71c4 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 9592d17db32..c5b091807ee 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 6a76927c997..6a5e56a782b 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; -- GitLab From e550e17ffeb8cf8db27724eaf2ad05f77388afb9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:52 +0100 Subject: [PATCH 1368/2509] 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 --- sound/soc/codecs/ac97.c | 2 +- sound/soc/codecs/ac97.h | 2 +- sound/soc/codecs/ak4535.c | 8 ++++---- sound/soc/codecs/ak4535.h | 2 +- sound/soc/codecs/cs4270.c | 8 ++++---- sound/soc/codecs/cs4270.h | 2 +- sound/soc/codecs/tlv320aic3x.c | 8 ++++---- sound/soc/codecs/tlv320aic3x.h | 2 +- sound/soc/codecs/uda1380.c | 6 +++--- sound/soc/codecs/uda1380.h | 2 +- sound/soc/codecs/wm8510.c | 10 +++++----- sound/soc/codecs/wm8510.h | 2 +- sound/soc/codecs/wm8731.c | 8 ++++---- sound/soc/codecs/wm8731.h | 2 +- sound/soc/codecs/wm8750.c | 8 ++++---- sound/soc/codecs/wm8750.h | 2 +- sound/soc/codecs/wm8753.c | 28 ++++++++++++++-------------- sound/soc/codecs/wm8753.h | 2 +- sound/soc/codecs/wm8990.c | 12 ++++++------ sound/soc/codecs/wm8990.h | 2 +- sound/soc/codecs/wm9712.c | 2 +- sound/soc/codecs/wm9712.h | 2 +- sound/soc/codecs/wm9713.c | 10 +++++----- sound/soc/codecs/wm9713.h | 2 +- 24 files changed, 67 insertions(+), 67 deletions(-) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index e4516f3ce64..61fd96ca7bc 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 2bf6d69fd06..281aa42e2bb 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 469266e881d..b26003c4f3e 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 fc686ddf753..e9fe30e2c05 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 e73fcfd9f5c..9deb8c74fdf 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 0ced49b7804..adc6cd9667d 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 954d39b7c04..b1dce5f459d 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 e6009461063..d76c079b86e 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 6d5335b14d5..a52d6d9e007 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 f9d885c8bf0..50c603e2c9f 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 b549f6753ab..67325fd9544 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 c862e7b7d53..f5d2e42eb3f 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 3ff42ad65ed..369d39c3f74 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 5bcab6a7afb..99f2e3c60e3 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 eb460c9aa63..e23cb09f0d1 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 a97a54a6348..8ef30e628b2 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 be01a738f18..8604809f0c3 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 95e2a1f5316..44f5f1ff0cc 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 a1371b73ba7..3ecce5168e9 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 bf9f8823dfc..6bea5748528 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 47390113bd0..9fc8edd8222 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 719105d61e6..d29e8a18ca6 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 a4806189044..38d1fe0971f 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 d357b6c8134..63b8d81756e 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); -- GitLab From 8cf7b2b393b26b9ba1ccbeeb271a88e51d58f3e3 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:00 +0100 Subject: [PATCH 1369/2509] 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 --- sound/soc/fsl/fsl_dma.c | 2 +- sound/soc/fsl/fsl_dma.h | 2 +- sound/soc/fsl/fsl_ssi.c | 24 ++++++++++++------------ sound/soc/fsl/fsl_ssi.h | 4 ++-- sound/soc/fsl/mpc8610_hpcd.c | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 78de7168d2b..da2bc590286 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 430a6ce8b0d..385d4a42603 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 f588545698f..71bff33f552 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 c5ce88e1565..83b44d700e3 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 8820c3f8d17..59d7e49bd66 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; -- GitLab From 8687eb8bded8c3c5842a85bd0c30e43fc5a3e0e0 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:07 +0100 Subject: [PATCH 1370/2509] 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 --- sound/soc/omap/n810.c | 4 ++-- sound/soc/omap/omap-mcbsp.c | 16 ++++++++-------- sound/soc/omap/omap-mcbsp.h | 2 +- sound/soc/omap/omap-pcm.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 74f4599b4d7..d1233c01398 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 40d87e6d0de..00b0c9d73cd 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 9965fd4b042..ed8afb55067 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 62370202c64..e092f3d836d 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; -- GitLab From 917f93ac80a1c007d4a3ce269a3712f93a75728f Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:11 +0100 Subject: [PATCH 1371/2509] 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 --- sound/soc/pxa/corgi.c | 4 ++-- sound/soc/pxa/poodle.c | 4 ++-- sound/soc/pxa/pxa2xx-ac97.c | 14 +++++++------- sound/soc/pxa/pxa2xx-ac97.h | 2 +- sound/soc/pxa/pxa2xx-i2s.c | 14 +++++++------- sound/soc/pxa/pxa2xx-i2s.h | 2 +- sound/soc/pxa/pxa2xx-pcm.c | 2 +- sound/soc/pxa/spitz.c | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index db18ef68b69..782afbf7ada 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 36cbf69f5f8..ce25b6bf340 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 cb947956ed1..b458667538c 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 b8ccfee095c..e390de8edcd 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 35090c2870f..9c06553b926 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 4435bd9f884..e2def441153 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 01ad7bf716b..2df03ee5819 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 ec18163fddd..fd1abc7b08d 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; -- GitLab From 1992a6fbd929196aebe95e0e7b04c4da66c3bfec Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:24 +0100 Subject: [PATCH 1372/2509] 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 --- sound/soc/s3c24xx/neo1973_wm8753.c | 12 ++++++------ sound/soc/s3c24xx/s3c2412-i2s.c | 14 +++++++------- sound/soc/s3c24xx/s3c2412-i2s.h | 2 +- sound/soc/s3c24xx/s3c2443-ac97.c | 10 +++++----- sound/soc/s3c24xx/s3c24xx-ac97.h | 2 +- sound/soc/s3c24xx/s3c24xx-i2s.c | 14 +++++++------- sound/soc/s3c24xx/s3c24xx-i2s.h | 2 +- sound/soc/s3c24xx/s3c24xx-pcm.c | 2 +- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index f053e85ff60..51a4ce3dbd1 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 c463a82dec3..ee4676ed128 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 27f48e1ffa8..aac08a25e54 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 533565b61b2..783349b7fed 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 bf03e8ed16c..a96dcadf28b 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 42e96b5ff82..397524282b5 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 537b4ecce8a..726d91cf4e1 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 ef599745159..cef79b34dc6 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; -- GitLab From 53640650ffe07f6201ecae0b0dca078b97327247 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:29 +0100 Subject: [PATCH 1373/2509] 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 --- sound/soc/sh/dma-sh7760.c | 2 +- sound/soc/sh/hac.c | 2 +- sound/soc/sh/sh7760-ac97.c | 2 +- sound/soc/sh/ssi.c | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 7a3ce80d672..9faa12622d0 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 b7b676b3d67..df7bc345c32 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 846d1b3a630..92bfaf4774a 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 3388bc3d62d..55c3464163a 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, -- GitLab From c1286b8671135006eeb66b0267fa2895561b78e4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 Jul 2008 19:26:03 +0100 Subject: [PATCH 1374/2509] 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 --- sound/soc/soc-dapm.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 94296b5dc58..d18ebc62786 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: -- GitLab From 3fccd8b1bf716f1314c76689a3554ea37ad282b6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 Jul 2008 19:26:04 +0100 Subject: [PATCH 1375/2509] 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 --- sound/soc/soc-dapm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d18ebc62786..2c87061c2a6 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); -- GitLab From 7e2574050e6af203f0c94915c98c53ce1fc48044 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 8 Jul 2008 11:50:09 +0200 Subject: [PATCH 1376/2509] 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 --- sound/pci/hda/patch_sigmatel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c4f3489376c..a6d138831e2 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; -- GitLab From 8c6529dbf881303920a415c2d14a500218661949 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:19:13 +0100 Subject: [PATCH 1377/2509] 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 --- include/sound/soc.h | 21 +++++++ sound/soc/soc-core.c | 140 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 153 insertions(+), 8 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 778e57e74dc..1890d87c520 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 4d626b47b2f..83f1190293a 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); -- GitLab From 64105cfd65df74fdf82c1d053b2c9953304a94ea Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:19:18 +0100 Subject: [PATCH 1378/2509] 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 --- sound/soc/at32/playpaq_wm8510.c | 16 ++++----- sound/soc/at91/eti_b1_wm8731.c | 18 +++++----- sound/soc/davinci/davinci-evm.c | 6 ++-- sound/soc/fsl/mpc8610_hpcd.c | 58 +++++++++++++----------------- sound/soc/omap/n810.c | 6 ++-- sound/soc/pxa/corgi.c | 8 ++--- sound/soc/pxa/poodle.c | 8 ++--- sound/soc/pxa/spitz.c | 8 ++--- sound/soc/s3c24xx/neo1973_wm8753.c | 26 +++++++------- 9 files changed, 71 insertions(+), 83 deletions(-) diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index 18ac7d7391c..fd62f256975 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 9d4213963c2..d532de95424 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 4249e6a8574..5e2c306399e 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 59d7e49bd66..4bdc9d8fc90 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 d1233c01398..e53c055412c 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 782afbf7ada..c0294464a23 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 ce25b6bf340..65a4e9a8c39 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 fd1abc7b08d..64385797da5 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 51a4ce3dbd1..4d7a9aa15f1 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 = { -- GitLab From ac8615baf279f9bcb90c8ae017321d63a94e1762 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:20:39 +0100 Subject: [PATCH 1379/2509] 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 --- sound/soc/omap/n810.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index e53c055412c..02cec96859b 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); } -- GitLab From 6f48413dd0f28d81a20fba2e264dd1b9f205893e Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:21:52 +0100 Subject: [PATCH 1380/2509] 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 --- sound/soc/at32/playpaq_wm8510.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index fd62f256975..fee5f8e5895 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; -- GitLab From bd5d06eb8f0b9e0eb117b9c45c254d577ec2e273 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:30:30 +0100 Subject: [PATCH 1381/2509] 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 --- sound/drivers/vx/vx_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 1dfe6948e6f..efd22e92bce 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; } -- GitLab From 7fc077fba5f8896c6fed3b35c5a10e7fdae82bbe Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:52:10 +0100 Subject: [PATCH 1382/2509] 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 --- sound/pcmcia/vx/vxp_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c index 157b0b539f3..99bf2a65a6f 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 */ -- GitLab From ee2da99782d717b264d5c309a2084ca85e9a64ff Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 9 Jul 2008 10:28:41 +0200 Subject: [PATCH 1383/2509] 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 --- include/sound/seq_kernel.h | 2 +- sound/core/seq/seq_clientmgr.c | 2 +- sound/core/seq/seq_device.c | 6 ++---- sound/core/sound.c | 8 ++++---- sound/core/timer.c | 6 +++--- sound/ppc/daca.c | 2 -- sound/ppc/tumbler.c | 2 -- 7 files changed, 11 insertions(+), 17 deletions(-) diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index f023c1b97f8..3d9afb6a8c9 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 47cfa5186e3..7a1545d2d95 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 2f00ad28a2b..05410e536a4 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 6c8ab48c689..09a94953745 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 9d8184a2c2d..0af337efc64 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 ca9452901a5..8a5b2903193 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 3f8d7164cef..009df8dd37a 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) -- GitLab From af13452820d075cb7153fe155ca796e64038d7e5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 Jul 2008 19:13:30 +0200 Subject: [PATCH 1384/2509] 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 --- sound/isa/wavefront/wavefront_synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 95eeca16335..0bb9b925660 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; -- GitLab From 76d39d0a1947fee4c29976e507fb93188eaa2b38 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 8 Jul 2008 19:45:20 +0400 Subject: [PATCH 1385/2509] 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 --- sound/soc/pxa/tosa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index dba7689c508..b6edb61a3a3 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 */ -- GitLab From a84534dc179d3e9f501e5a12598cc5271cd28f5b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 8 Jul 2008 19:45:42 +0400 Subject: [PATCH 1386/2509] 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 --- sound/soc/pxa/pxa2xx-ac97.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index b458667538c..059af815ea0 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); -- GitLab From bf41534506a0572c06c8f34d12aa489be4c8780e Mon Sep 17 00:00:00 2001 From: Richard Chan Date: Wed, 9 Jul 2008 19:39:07 +0200 Subject: [PATCH 1387/2509] 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 --- sound/usb/usbquirks.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index b7ab3ee7647..d675050210d 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), -- GitLab From 4a161d235b68eb7234f40106560c488a1bdb3851 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 9 Jul 2008 16:27:56 +0200 Subject: [PATCH 1388/2509] 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 --- include/asm-mips/mach-au1x00/au1xxx_psc.h | 8 + sound/soc/Kconfig | 1 + sound/soc/Makefile | 2 +- sound/soc/au1x/Kconfig | 32 ++ sound/soc/au1x/Makefile | 13 + sound/soc/au1x/dbdma2.c | 421 ++++++++++++++++++++++ sound/soc/au1x/psc-ac97.c | 387 ++++++++++++++++++++ sound/soc/au1x/psc-i2s.c | 414 +++++++++++++++++++++ sound/soc/au1x/psc.h | 53 +++ sound/soc/au1x/sample-ac97.c | 144 ++++++++ 10 files changed, 1474 insertions(+), 1 deletion(-) create mode 100644 sound/soc/au1x/Kconfig create mode 100644 sound/soc/au1x/Makefile create mode 100644 sound/soc/au1x/dbdma2.c create mode 100644 sound/soc/au1x/psc-ac97.c create mode 100644 sound/soc/au1x/psc-i2s.c create mode 100644 sound/soc/au1x/psc.h create mode 100644 sound/soc/au1x/sample-ac97.c diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h index dae4eca2417..892b7f168eb 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 b939e22db7b..f743530add8 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 3645f959c26..933a66d3080 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 00000000000..410a893aa66 --- /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 00000000000..6c6950b8003 --- /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 00000000000..1466d932880 --- /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 00000000000..57facbad682 --- /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 00000000000..ba4b5c199f2 --- /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 00000000000..8fdb1a04a07 --- /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 00000000000..f75ae7f62c3 --- /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 "); -- GitLab From c85ceac97487580e39daaf57858513246e425647 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 10 Jul 2008 11:01:06 +0200 Subject: [PATCH 1389/2509] 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 --- sound/usb/usbquirks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index d675050210d..3eb12feeae5 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), -- GitLab From 83a1a3974f33d45d6631363738db737624a32e82 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 10 Jul 2008 11:05:42 +0200 Subject: [PATCH 1390/2509] ALSA: usb-audio: add some Yamaha USB MIDI quirks Add quirk entries for four Yamaha USB MIDI devices. Signed-off-by: Clemens Ladisch --- sound/usb/usbquirks.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 3eb12feeae5..9ea726c049c 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), -- GitLab From ca201c8230de336c3684aa3f3422d0c3f02bcef9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 12:33:20 +0200 Subject: [PATCH 1391/2509] 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 --- include/asm-x86/mach-visws/entry_arch.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/asm-x86/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h index b183fa6d83d..9283b60a1dd 100644 --- a/include/asm-x86/mach-visws/entry_arch.h +++ b/include/asm-x86/mach-visws/entry_arch.h @@ -1,3 +1,9 @@ +/* + * 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 @@ -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 -- GitLab From 42a2f217a5e324ed5f2373ab1b7a0a15187c4d6c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 12:35:46 +0200 Subject: [PATCH 1392/2509] 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 --- include/asm-x86/mach-visws/entry_arch.h | 34 ++----------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/include/asm-x86/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h index 9283b60a1dd..86be554342d 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" -- GitLab From 613526677a74c2b3d1b1696ea7334b2cf35155b3 Mon Sep 17 00:00:00 2001 From: sedji gaouaou Date: Thu, 10 Jul 2008 10:15:35 +0100 Subject: [PATCH 1393/2509] [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 --- arch/arm/mach-at91/Kconfig | 29 ++- arch/arm/mach-at91/Makefile | 4 + arch/arm/mach-at91/at91sam9260.c | 16 ++ arch/arm/mach-at91/at91sam9260_devices.c | 44 +++-- arch/arm/mach-at91/board-sam9g20ek.c | 218 +++++++++++++++++++++++ arch/arm/mach-at91/clock.c | 19 +- arch/arm/mach-at91/pm.c | 2 +- arch/arm/mm/Kconfig | 4 +- drivers/net/Kconfig | 2 +- drivers/usb/gadget/at91_udc.c | 4 +- include/asm-arm/arch-at91/at91sam9260.h | 11 ++ include/asm-arm/arch-at91/board.h | 2 +- include/asm-arm/arch-at91/cpu.h | 7 + include/asm-arm/arch-at91/hardware.h | 2 +- include/asm-arm/arch-at91/timex.h | 5 + sound/soc/at91/at91-ssc.c | 2 +- 16 files changed, 342 insertions(+), 29 deletions(-) create mode 100644 arch/arm/mach-at91/board-sam9g20ek.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index cae5c67dc31..5bad6b9b00d 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 932d17109e8..7d641f97516 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 ee26550cdc2..380f12a1220 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 26f5cacbec3..86cba4ac29b 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 00000000000..45617c20124 --- /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 e8ce8f0f3ed..464bdbbf74d 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 aa863c15770..8ab4feb1ec5 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 33ed048502a..750d895cd28 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 9f6cc8a5607..be3b13cf417 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 274c60a970c..b6b2a0a5ba3 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 c8934fe34dc..889872a3f2a 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 1f247028686..94de788da76 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 7145166826a..52df794205c 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 2c826d8247a..016a3a3f663 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 6e084eb839d..298d8313cda 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 bc35d00a38f..1a426095014 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 -- GitLab From 3ef8191f43cfd936ea00b7483ea0acf2f0303a23 Mon Sep 17 00:00:00 2001 From: sedji gaouaou Date: Thu, 10 Jul 2008 10:12:14 +0100 Subject: [PATCH 1394/2509] [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 --- arch/arm/configs/at91sam9g20ek_defconfig | 1168 ++++++++++++++++++++++ 1 file changed, 1168 insertions(+) create mode 100644 arch/arm/configs/at91sam9g20ek_defconfig diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig new file mode 100644 index 00000000000..c0686384736 --- /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 -- GitLab From 93aa7f8a12d1b229bcee12a1100a6df4945f5432 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 7 May 2008 21:10:13 +0800 Subject: [PATCH 1395/2509] [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 --- crypto/cryptd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crypto/cryptd.c b/crypto/cryptd.c index b150de56205..f38e1473b72 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(); } -- GitLab From c6580eb8b17d64f0d6ad25c86a034adbda5ab4e1 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:14:10 +0800 Subject: [PATCH 1396/2509] [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 --- crypto/Makefile | 2 + crypto/ripemd.h | 26 ++++ crypto/rmd128.c | 344 ++++++++++++++++++++++++++++++++++++++++++ crypto/rmd160.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 760 insertions(+) create mode 100644 crypto/ripemd.h create mode 100644 crypto/rmd128.c create mode 100644 crypto/rmd160.c diff --git a/crypto/Makefile b/crypto/Makefile index ca024418f4f..1efb5563566 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 00000000000..2858e2266bd --- /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 00000000000..22cc13be403 --- /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 00000000000..a8a9d3d7046 --- /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"); -- GitLab From fd4adf1a0b1923f6126835e1097b2997eb0d27e2 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:16:36 +0800 Subject: [PATCH 1397/2509] [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 --- crypto/tcrypt.c | 29 ++++- crypto/tcrypt.h | 292 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 320 insertions(+), 1 deletion(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e47f6e02133..f6220b35197 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 47bc0ecb897..89068233acf 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", + } }; /* @@ -816,6 +946,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 */ -- GitLab From 82798f90fb13fd934a15ed56fee227fe808dcbe8 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:17:37 +0800 Subject: [PATCH 1398/2509] [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 --- crypto/Kconfig | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 864456c140f..cfc521a0d55 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 -- GitLab From b10c170638c1f75bf582a75442fcdf27057ff537 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 7 May 2008 22:19:38 +0800 Subject: [PATCH 1399/2509] [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 --- crypto/tcrypt.c | 8 -------- crypto/tcrypt.h | 7 ------- 2 files changed, 15 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index f6220b35197..285c093abb7 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 89068233acf..af91f0cd15a 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 -- GitLab From 3c42cbc2e01238778db92e16873a6e6f015a00af Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:28:27 +0800 Subject: [PATCH 1400/2509] [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 --- drivers/crypto/hifn_795x.c | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 81f3f950cd7..d7a51ee26ee 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 | -- GitLab From 7808f0738f9ac5cff05bd89ee457334b9a029b5c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:29:42 +0800 Subject: [PATCH 1401/2509] [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 --- drivers/crypto/hifn_795x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d7a51ee26ee..e5c3bc4c4a1 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, -- GitLab From 9e70a408ad66846bc98dc026efe0384ef68373fc Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:31:35 +0800 Subject: [PATCH 1402/2509] [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 --- drivers/crypto/hifn_795x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index e5c3bc4c4a1..cce6e6f1baa 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; } /* -- GitLab From 94eaa1bd7ca67e8f57919da96cbb41c215ef20cb Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:32:28 +0800 Subject: [PATCH 1403/2509] [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 --- drivers/crypto/hifn_795x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index cce6e6f1baa..4e89cd8f664 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); -- GitLab From d069033b42b392662320f71e319296a14d57ff3a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:33:37 +0800 Subject: [PATCH 1404/2509] [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 --- drivers/crypto/hifn_795x.c | 42 +++++++++++++------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 4e89cd8f664..4428e8e68a0 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; -- GitLab From 136f702f51a4bfa38003660768e7153823fff8a1 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:34:27 +0800 Subject: [PATCH 1405/2509] [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 --- drivers/crypto/hifn_795x.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 4428e8e68a0..366e974d0e5 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; } -- GitLab From 281d6bd45385c689e7c03c9ff2434c143971682d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:35:07 +0800 Subject: [PATCH 1406/2509] [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 --- drivers/crypto/hifn_795x.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 366e974d0e5..d09338f70dc 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; -- GitLab From 4b804b53ef5a3c1a49c11bfff2754e0334cc932e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:35:47 +0800 Subject: [PATCH 1407/2509] [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 --- drivers/crypto/hifn_795x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d09338f70dc..a4b1cea59ae 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, -- GitLab From 6cd3d674ddd1706226d4c395440ef1997fd72381 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:36:17 +0800 Subject: [PATCH 1408/2509] [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 --- drivers/crypto/hifn_795x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index a4b1cea59ae..d6f042370d4 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 -- GitLab From 85e7e60b856141cc9831e11cdfc8e9265886abac Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:36:54 +0800 Subject: [PATCH 1409/2509] [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 --- drivers/crypto/hifn_795x.c | 205 +++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 101 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d6f042370d4..c9fe18d5348 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) { -- GitLab From 692af5da779e018fc6a3b480b67adb33e3c6e1f0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:37:29 +0800 Subject: [PATCH 1410/2509] [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 --- drivers/crypto/hifn_795x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9fe18d5348..459d283b94c 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; -- GitLab From a558f1d4f8730f055b004b4c8ca1605aeb957daa Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 8 May 2008 19:27:47 +0800 Subject: [PATCH 1411/2509] [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 --- crypto/tcrypt.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 285c093abb7..69eb29e1a53 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])); } -- GitLab From ba6b0398721524ec817f74ea3492b48fa79de52f Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:25:42 +0800 Subject: [PATCH 1412/2509] [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 --- crypto/ripemd.h | 17 +++++++++++++++++ crypto/rmd128.c | 16 ++++++++-------- crypto/rmd160.c | 20 ++++++++++---------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/crypto/ripemd.h b/crypto/ripemd.h index 2858e2266bd..c57a2d4ce8d 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 22cc13be403..f72d2ce848d 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 a8a9d3d7046..80d647aada6 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 */ -- GitLab From c555c28d9da517579085a00fc80e725b0b5d9fce Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:27:02 +0800 Subject: [PATCH 1413/2509] [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 --- crypto/Makefile | 2 + crypto/rmd256.c | 363 ++++++++++++++++++++++++++++++++++++++++++ crypto/rmd320.c | 412 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 777 insertions(+) create mode 100644 crypto/rmd256.c create mode 100644 crypto/rmd320.c diff --git a/crypto/Makefile b/crypto/Makefile index 1efb5563566..807656b64e0 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 00000000000..060ee81cb8a --- /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 00000000000..b39c0543a8f --- /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"); -- GitLab From 2998db37b5c62890ff1a0d48abd76ada13ebc554 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:29:35 +0800 Subject: [PATCH 1414/2509] [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 --- crypto/tcrypt.c | 21 +++++++- crypto/tcrypt.h | 136 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 69eb29e1a53..e0ea4d53f25 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 af91f0cd15a..20bd5fef0c0 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -293,6 +293,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 */ -- GitLab From 534fe2c1c3ffbbc3db66dba0783c82d3b345fd33 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:30:27 +0800 Subject: [PATCH 1415/2509] [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 --- crypto/Kconfig | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index cfc521a0d55..5963a9566fe 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 -- GitLab From 004a403c2e954734090a69aedc7f4f822bdcc142 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 20:41:47 +0800 Subject: [PATCH 1416/2509] [CRYPTO] hash: Add asynchronous hash support This patch adds asynchronous hash and digest support. Signed-off-by: Loc Ho Signed-off-by: Herbert Xu --- crypto/Makefile | 1 + crypto/ahash.c | 106 +++++++++++++++++++++++ crypto/api.c | 8 +- crypto/digest.c | 81 +++++++++++++++++ crypto/hash.c | 102 ++++++++++++++++++++-- crypto/internal.h | 1 + include/crypto/algapi.h | 36 ++++++++ include/linux/crypto.h | 187 +++++++++++++++++++++++++++++++++++++++- 8 files changed, 507 insertions(+), 15 deletions(-) create mode 100644 crypto/ahash.c diff --git a/crypto/Makefile b/crypto/Makefile index 807656b64e0..d4f3ed857df 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 00000000000..a83e035d9a3 --- /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 0a0f41ef255..d06e33270ab 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 b526cc348b7..025c9aea24e 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 7dcff671c19..f9400a014e7 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 32f4c214560..683fcb2d91f 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 60d06e784be..fef272a8cee 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 425824bd49f..b6efe569128 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 */ -- GitLab From b8a28251c2066a2ac6481fc49ced5eb7f078e49b Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 21:23:00 +0800 Subject: [PATCH 1417/2509] [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 --- crypto/Kconfig | 1 + crypto/cryptd.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 5963a9566fe..795e31c8aec 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 f38e1473b72..d3ecd7e73b7 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); -- GitLab From cde0e2c819aad91ed1e1c2e8aa64c16e7774c769 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 21:24:51 +0800 Subject: [PATCH 1418/2509] [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 --- crypto/tcrypt.c | 76 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e0ea4d53f25..e99cb4bc546 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, -- GitLab From 0bea3dc1e2d85deb9e0bc523949d5c812f65b556 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 15 May 2008 14:29:46 +0800 Subject: [PATCH 1419/2509] [CRYPTO] hifn: Remove duplicated include Removed duplicated include file . Signed-off-by: Huang Weiyi Signed-off-by: Evgeniy Polyakov Signed-off-by: Herbert Xu --- drivers/crypto/hifn_795x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 459d283b94c..d0f71a1c1a4 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- GitLab From 0f923a2aab7baa94c5fef498384151af1cd72cba Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Tue, 20 May 2008 11:41:48 +0800 Subject: [PATCH 1420/2509] [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 --- crypto/rmd128.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/crypto/rmd128.c b/crypto/rmd128.c index f72d2ce848d..89a535aa6eb 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)); -- GitLab From c928a0cddd070720268013fd012508059aa3de5a Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:32:52 +1000 Subject: [PATCH 1421/2509] [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 --- crypto/rmd160.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/crypto/rmd160.c b/crypto/rmd160.c index 80d647aada6..136e31f56d5 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)); -- GitLab From 2952ff1a598ce300c911d00d82872d00ca8b61ca Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:33:44 +1000 Subject: [PATCH 1422/2509] [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 --- crypto/rmd256.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/crypto/rmd256.c b/crypto/rmd256.c index 060ee81cb8a..88f2203751a 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)); -- GitLab From feedfdaa7bc02694c122d2d5246184248fb04513 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:54:34 +1000 Subject: [PATCH 1423/2509] [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 --- crypto/rmd320.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/crypto/rmd320.c b/crypto/rmd320.c index b39c0543a8f..5b172f89e0c 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)); -- GitLab From 0936a944068ef68f8b19f437e03f4654c29f2423 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 26 May 2008 21:21:07 +1000 Subject: [PATCH 1424/2509] [CRYPTO] hifn: Simplify code using ARRAY_SIZE() macro Signed-off-by: Robert P. J. Day Signed-off-by: Herbert Xu --- drivers/crypto/hifn_795x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d0f71a1c1a4..4d22b21bd3e 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; -- GitLab From 5cdcc22f25b0766fe16d5dd8e3b2efc91fa4da6e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 2 Jun 2008 21:30:38 +1000 Subject: [PATCH 1425/2509] [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 --- crypto/rmd128.c | 4 ++-- crypto/rmd160.c | 4 ++-- crypto/rmd256.c | 4 ++-- crypto/rmd320.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 89a535aa6eb..1a481df6691 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 136e31f56d5..e9fd5f6a0ac 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 88f2203751a..b0885269070 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 5b172f89e0c..dba03ecf536 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)); -- GitLab From d729de23e86bbbb28adf6c3ded3651ea4ad8c539 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 3 Jun 2008 20:00:16 +1000 Subject: [PATCH 1426/2509] [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 --- crypto/tcrypt.c | 16 +++++++++ crypto/tcrypt.h | 93 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e99cb4bc546..ffc1ec6d279 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 20bd5fef0c0..801e0c28886 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. */ -- GitLab From 9c4a79653b35efc9d6790c295e22f79f4b361125 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Mon, 23 Jun 2008 19:50:15 +0800 Subject: [PATCH 1427/2509] 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 --- drivers/crypto/Kconfig | 16 + drivers/crypto/Makefile | 1 + drivers/crypto/talitos.c | 1467 ++++++++++++++++++++++++++++++++++++++ drivers/crypto/talitos.h | 200 ++++++ 4 files changed, 1684 insertions(+) create mode 100644 drivers/crypto/talitos.c create mode 100644 drivers/crypto/talitos.h diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 43b71b69daa..249c1358058 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 c0327f0dadc..d29d2cd0e65 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 00000000000..e12331296a0 --- /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 00000000000..de0e37734af --- /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 -- GitLab From 81bef0150074d677d8cbd4e971a8ce6c9746a1fc Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Wed, 25 Jun 2008 14:38:47 +0800 Subject: [PATCH 1428/2509] 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 --- drivers/crypto/Kconfig | 9 + drivers/crypto/Makefile | 1 + drivers/crypto/ixp4xx_crypto.c | 1506 ++++++++++++++++++++++++++++++++ 3 files changed, 1516 insertions(+) create mode 100644 drivers/crypto/ixp4xx_crypto.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 249c1358058..eb2ec2e0a14 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 d29d2cd0e65..73557b2968d 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 00000000000..42a107fe923 --- /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"); + -- GitLab From 4b22f0ddb6564210c9ded7ba25b2a1007733e784 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 3 Jul 2008 14:57:30 +0800 Subject: [PATCH 1429/2509] 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 --- crypto/tcrypt.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index ffc1ec6d279..87f08f9b090 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])); } } } -- GitLab From b43e726b32b85713c7c56b6545cf71c2b02b5e1a Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Thu, 3 Jul 2008 19:03:31 +0800 Subject: [PATCH 1430/2509] 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 --- drivers/crypto/padlock-aes.c | 4 ++-- drivers/crypto/padlock-sha.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index bb30eb9b93e..54a2a166e56 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 c666b4e0933..40d5680fa01 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; } -- GitLab From 70bcaca75389a6c011ddc866eb1743b070a838b0 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Thu, 3 Jul 2008 19:08:46 +0800 Subject: [PATCH 1431/2509] 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 --- drivers/crypto/talitos.c | 93 +++++++++++++++++++++++++++++----------- drivers/crypto/talitos.h | 3 +- 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index e12331296a0..e8459e00da3 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 de0e37734af..c48a405abf7 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) -- GitLab From ebbcf3369224ae7d23bfee06d8c5ea87a9541db5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 3 Jul 2008 19:14:02 +0800 Subject: [PATCH 1432/2509] 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 --- drivers/crypto/talitos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index e8459e00da3..8c270cd7baa 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, -- GitLab From bd699f2df6dbc2f4cba528fe598bd63a4d3702c5 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:42:24 +0800 Subject: [PATCH 1433/2509] 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 --- crypto/camellia.c | 84 ++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/crypto/camellia.c b/crypto/camellia.c index 493fee7e0a8..b1cc4de6493 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 */ -- GitLab From b2b6a1720db65c97885ab9fc51fa23be47573bf4 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:45:57 +0800 Subject: [PATCH 1434/2509] crypto: rmd128 - sparse annotations Signed-off-by: Harvey Harrison Signed-off-by: Herbert Xu --- crypto/rmd128.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 1a481df6691..5de6fa2a76f 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); -- GitLab From caee16883a235b1b042282276859e7d5901fad21 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:48:58 +0800 Subject: [PATCH 1435/2509] 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 --- crypto/rmd160.c | 8 ++++---- crypto/rmd256.c | 8 ++++---- crypto/rmd320.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crypto/rmd160.c b/crypto/rmd160.c index e9fd5f6a0ac..f001ec775e1 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 b0885269070..e3de5b4cb47 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 dba03ecf536..b143d66e42c 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); -- GitLab From ca786dc738f4f583b57b1bba7a335b5e8233f4b0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 20:23:56 +0800 Subject: [PATCH 1436/2509] 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 --- crypto/ahash.c | 2 +- crypto/digest.c | 2 +- crypto/hash.c | 2 +- crypto/hmac.c | 16 ++++++++++------ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crypto/ahash.c b/crypto/ahash.c index a83e035d9a3..8c1f918a687 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 025c9aea24e..d63d5d96fee 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 f9400a014e7..0d7caa9ab74 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 14c6351e639..7ff2d6a8c7d 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; -- GitLab From 166247f46a9c866e6f7f7d2212be875fb82212a1 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 20:54:35 +0800 Subject: [PATCH 1437/2509] 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 --- crypto/ahash.c | 1 - crypto/digest.c | 1 - crypto/hash.c | 1 - include/linux/crypto.h | 7 ++----- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/crypto/ahash.c b/crypto/ahash.c index 8c1f918a687..e6e5906ca80 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 d63d5d96fee..bf332982c50 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 0d7caa9ab74..140a75565f1 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 b6efe569128..68ef293644d 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( -- GitLab From b8454eebe380677789735fd6bad368af2e6b2d1e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 7 Jul 2008 22:41:31 +0800 Subject: [PATCH 1438/2509] 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 --- crypto/Kconfig | 9 ++ crypto/Makefile | 2 +- crypto/prng.c | 410 ++++++++++++++++++++++++++++++++++++++++++++++++ crypto/prng.h | 27 ++++ 4 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 crypto/prng.c create mode 100644 crypto/prng.h diff --git a/crypto/Kconfig b/crypto/Kconfig index 795e31c8aec..43b7473ff19 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 d4f3ed857df..ef61b3b6466 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 00000000000..24e4f3282c5 --- /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 00000000000..1ac9be5009b --- /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 + -- GitLab From 20036252fc61c624a49770fb89684ea5cfdfa05e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 22:19:53 +0800 Subject: [PATCH 1439/2509] 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 --- crypto/ahash.c | 91 +++++++++++++++++++++++++++++++++- include/crypto/internal/hash.h | 41 +++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 include/crypto/internal/hash.h diff --git a/crypto/ahash.c b/crypto/ahash.c index e6e5906ca80..27128f2c687 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 00000000000..93ac4228022 --- /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 */ + -- GitLab From 5773a3e6e396d5fd9de58372abe6a86b7e258e3e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 8 Jul 2008 20:54:28 +0800 Subject: [PATCH 1440/2509] 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 --- crypto/Kconfig | 2 +- crypto/crc32c.c | 128 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 43b7473ff19..ea503572fcb 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 0dcf64a74e6..a882d9e4e63 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); -- GitLab From 18e33e6d5cc0495826f5245777cd267732815e01 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 10 Jul 2008 16:01:22 +0800 Subject: [PATCH 1441/2509] 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 --- crypto/cryptd.c | 1 + crypto/digest.c | 1 + crypto/hash.c | 1 + crypto/tcrypt.c | 1 + include/crypto/algapi.h | 36 -------- include/crypto/hash.h | 154 +++++++++++++++++++++++++++++++++ include/crypto/internal/hash.h | 37 ++++++++ include/linux/crypto.h | 136 ----------------------------- 8 files changed, 195 insertions(+), 172 deletions(-) create mode 100644 include/crypto/hash.h diff --git a/crypto/cryptd.c b/crypto/cryptd.c index d3ecd7e73b7..d29e06b350f 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 bf332982c50..ac0919460d1 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 140a75565f1..cb86b19fd10 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 87f08f9b090..59821a22d75 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 fef272a8cee..60d06e784be 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 00000000000..d12498ec8a4 --- /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 93ac4228022..917ae57bad4 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 68ef293644d..c43dc47fdf7 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 */ -- GitLab From 3952f17ed63434cc2154c3765ff97e1d4adab042 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Thu, 10 Jul 2008 18:29:18 +0800 Subject: [PATCH 1442/2509] 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 --- drivers/crypto/talitos.c | 111 ++++++++++++++++++++++++++++++++++----- 1 file changed, 99 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 8c270cd7baa..b11943dadef 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, } }; -- GitLab From 34ec8a0ae138c2787a550b930d29a9cce4900cee Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 10 Jul 2008 14:49:19 +0200 Subject: [PATCH 1443/2509] 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 --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 92a709be3c4..2807bc840d2 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), -- GitLab From 6dfff895fa33b8576f82a38cee8abe5f73561e24 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 18:37:51 +0100 Subject: [PATCH 1444/2509] libertas: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/wireless/libertas/if_cs.c | 2 +- drivers/net/wireless/libertas/if_sdio.c | 4 ++-- drivers/net/wireless/libertas/if_usb.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 54280e292ea..d075b448da9 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 51f664bbee9..3dd537be87d 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 36288b29abf..4dcd4092e0f 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; -- GitLab From 8187b4fb9c17ea8e2a71c0563434f3ee08aad0d7 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:56:51 +0100 Subject: [PATCH 1445/2509] bluetooth: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/bluetooth/bfusb.c | 3 ++- drivers/bluetooth/bt3c_cs.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index b990805806a..0c211adbc06 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 7703d6e06fd..593b7c59503 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]; -- GitLab From f61e761e2128c7ca0d044651b18928991ab03be2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:57:19 +0100 Subject: [PATCH 1446/2509] cyclades: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/char/cyclades.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index ef73e72daed..6bff9d87dc5 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)) { -- GitLab From 9ad46a6ac5422882d9f9a7f0d77ca0766f56bb6e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:58:24 +0100 Subject: [PATCH 1447/2509] cx25840: treat firmware data as const Signed-off-by: David Woodhouse Acked-by: Hans Verkuil Acked-by: Tyler Trafford Acked-by: Mike Isely --- .../media/video/cx25840/cx25840-firmware.c | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 620d295947a..8d489a4b957 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); -- GitLab From b0d31d6b28c7ca2ed78ce16ec649c0aac383a3fe Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:00:07 +0100 Subject: [PATCH 1448/2509] myri10ge: treat firmware data as const ... which means allocating our own buffer for reading it back. Signed-off-by: David Woodhouse --- drivers/net/myri10ge/myri10ge.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index e0d76c75aea..823bb6d3533 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); -- GitLab From c2ba47d776bf9a45e15f28fc73ad44877437bef9 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:01:40 +0100 Subject: [PATCH 1449/2509] vx222: treat firmware data as const Signed-off-by: David Woodhouse --- sound/pci/vx222/vx222_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index b4bfc1acde8..631f3a63999 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); -- GitLab From 93a9c901c88ba2b1bae9dd55e6243896b8a580f1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:03 +0100 Subject: [PATCH 1450/2509] riptide: treat firmware data as const Signed-off-by: David Woodhouse --- sound/pci/riptide/riptide.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 979f7da641c..6a359624734 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; -- GitLab From b8d21807a1a479e0214a03069a88e3e93492b72d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:28 +0100 Subject: [PATCH 1451/2509] pcxhr: treat firmware data as const Signed-off-by: David Woodhouse --- sound/pci/pcxhr/pcxhr_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 78aa81feaa4..957e6afe94f 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); -- GitLab From 2f0600b639777cbc1c0ae3f7bbbc982b0838e706 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:49 +0100 Subject: [PATCH 1452/2509] vx: treat firmware data as const Signed-off-by: David Woodhouse --- sound/drivers/vx/vx_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index 99538862e34..585af2eb143 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); -- GitLab From aafcd2f7d6790490bd921f04390bc210b386ecfa Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:10 +0100 Subject: [PATCH 1453/2509] ueagle-atm: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/usb/atm/ueagle-atm.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 5f71ff3aee3..cb01b5106ef 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)); -- GitLab From 3b216d186c6df2642b397dbb67fbb7884ead0d88 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:28 +0100 Subject: [PATCH 1454/2509] cxacru: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/usb/atm/cxacru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 5ea3093bc40..90583d6a594 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; -- GitLab From 0bc202e0fd84b8c8d042bdf9f0995e1e47bdbf59 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:45 +0100 Subject: [PATCH 1455/2509] aic94xx: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/scsi/aic94xx/aic94xx_sds.c | 12 ++++++------ drivers/scsi/aic94xx/aic94xx_sds.h | 4 ++-- drivers/scsi/aic94xx/aic94xx_seq.c | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 4446e3d584d..8630a75b287 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 bb9795a04dc..a06dc0114b8 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 f4272ac4c68..8f98e33155e 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); -- GitLab From 45ef0bdb18a37bcf102e2a18c757227f8b192a36 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:19 +0100 Subject: [PATCH 1456/2509] zd1201: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/wireless/zd1201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index d5c0c66188c..78baa0f7926 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; -- GitLab From f160ebcbeb6c9b79a770f22e14398158dac3de00 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:39 +0100 Subject: [PATCH 1457/2509] rt2x00: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/wireless/rt2x00/rt2x00.h | 4 ++-- drivers/net/wireless/rt2x00/rt2x00pci.h | 2 +- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b4bf1e09cf9..a74e1a5c56f 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 9d1cdb99431..b41967ecbf6 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 14bc7b28165..bb78de5290c 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 83cc0147f69..d5a6c21235c 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; -- GitLab From 8b72eb4333aba692a16339acf8a74d84b10d3568 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:55 +0100 Subject: [PATCH 1458/2509] p54: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/wireless/p54/p54usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 1610a7308c1..815c095ef79 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) { -- GitLab From 2f26e8afb22d79f655def146894595a39aeea1f8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:09:29 +0100 Subject: [PATCH 1459/2509] atmel: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/wireless/atmel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 438e63ecccf..d1acef7e0b1 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); -- GitLab From afd636e94d3cd99697f7291dbf957f0ca8a7544e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:10:26 +0100 Subject: [PATCH 1460/2509] irda-usb: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/irda/irda-usb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6f50ed7b183..18b471cd144 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; /* -- GitLab From 2c733a16784021c7c6a0c10e800937f0645d0a36 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:10:55 +0100 Subject: [PATCH 1461/2509] cxgb3: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/net/cxgb3/common.h | 5 +++-- drivers/net/cxgb3/t3_hw.c | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 579bee42a5c..8e8ebd78853 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 d405a932c73..47d51788a46 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++)); -- GitLab From 4f2a0c3cdbead635f8aae729f550fcabcb73d1a5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:11:44 +0100 Subject: [PATCH 1462/2509] bt8xx: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/media/video/bt8xx/bttv-cards.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 8ef0424c26c..1c56ae92ce7 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; -- GitLab From 99b6e4f511e38ea7beae35ee1b46b440151ce727 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:00 +0100 Subject: [PATCH 1463/2509] ttusb-dec: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/media/dvb/ttusb-dec/ttusb_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index fefdc05e84a..de5829b863f 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; -- GitLab From bc179153ae2334efe28cf4f3300e024da7d83753 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:23 +0100 Subject: [PATCH 1464/2509] dvb frontends: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/media/dvb/frontends/bcm3510.c | 5 +++-- drivers/media/dvb/frontends/nxt200x.c | 3 ++- drivers/media/dvb/frontends/or51211.c | 4 ++-- drivers/media/dvb/frontends/sp8870.c | 2 +- drivers/media/dvb/frontends/sp887x.c | 2 +- drivers/media/dvb/frontends/tda10048.c | 2 +- drivers/media/dvb/frontends/tda1004x.c | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index d268e65e777..cf5e576dfdc 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 23d02285254..af298358e82 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 7eaa4765593..6afe12aaca4 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 aa78aa14aad..1c9a9b4051b 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 49f55877f51..4543609e181 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 090fb7dd93c..0ab8d86b3ae 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 a0d63865356..1465ff77b0c 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]; -- GitLab From e62f89f2aebd57f48687f139c20cf6375693b622 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:42 +0100 Subject: [PATCH 1465/2509] 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 --- drivers/media/dvb/dvb-usb/cxusb.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 720fcd1c3c1..0286156704f 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; } } -- GitLab From 3a9282cacdb13466b9c745518237938434dbde0b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:13:08 +0100 Subject: [PATCH 1466/2509] gp8psk: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/media/dvb/dvb-usb/gp8psk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 2653120673b..d965a923f39 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) " -- GitLab From c63e87e90abb5d3ecd05d6c6eba94163bf8c1760 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:13:34 +0100 Subject: [PATCH 1467/2509] tuners: treat firmware data as const Signed-off-by: David Woodhouse --- drivers/media/common/tuners/tuner-xc2028.c | 2 +- drivers/media/common/tuners/xc5000.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 0cbde17bfbb..30eb07b7f9e 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 7cf4f5bdb2e..4878d6477a8 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; -- GitLab From fa6e1cb66e2f9d2d4703e7bd7dd50839bb10e4c3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 11:58:27 +0300 Subject: [PATCH 1468/2509] 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 --- sound/pci/maestro3.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index a536c59fbea..9dfba6eff85 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); } -- GitLab From b82a82d0a90af74847ae3e873a241dedf3786fd5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 14:40:00 +0300 Subject: [PATCH 1469/2509] 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 --- sound/pci/ymfpci/ymfpci_main.c | 59 ++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 29b3056c510..6298b29c66b 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); } -- GitLab From c6c1c94e8225c833d4c175622f8c2e70c7347a7d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 May 2008 10:05:08 -0700 Subject: [PATCH 1470/2509] dell_rbu: firmware data is const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse --- drivers/firmware/dell_rbu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 6a8b1e037e0..7430e218cda 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; -- GitLab From a13b04af713bfa60d44cbac956ab00d3a5793de7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 May 2008 10:05:08 -0700 Subject: [PATCH 1471/2509] x86 microcode: firmware data is const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse --- arch/x86/kernel/microcode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c index 69729e38b78..649dfd761f2 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; -- GitLab From ed5a2825feb79c424882c9d0f483172a91c93b54 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Thu, 29 May 2008 10:17:38 -0700 Subject: [PATCH 1472/2509] isight: treat firmware data as const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse --- drivers/usb/misc/isight_firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 9f30aa1f8a5..d94aa738760 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; -- GitLab From b561c74ae2832d32cc189ecd82863d31151cdcb5 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:36:45 +0100 Subject: [PATCH 1473/2509] 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 --- sound/drivers/vx/vx_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 1dfe6948e6f..efd22e92bce 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; } -- GitLab From 2bca76e89bc43f86136080536858048ebffab3e3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:37:15 +0100 Subject: [PATCH 1474/2509] 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 --- drivers/char/moxa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d57d3a61919..e21346da310 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)); -- GitLab From 9b8a3e4cb1361cf4b4a50916876e72f07a9037e9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:38:56 +0100 Subject: [PATCH 1475/2509] 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 --- drivers/media/video/cx18/cx18-av-firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 526e142156c..a1a6af6c1c8 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) { -- GitLab From 67852dc08c0782735d48ce1e2a6eb44cd02a6ff7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:45:58 +0100 Subject: [PATCH 1476/2509] 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 --- sound/pci/pcxhr/pcxhr_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index e6a4bfbb91b..d2f043278cf 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; } -- GitLab From fd4f80de4612cc5255c108a8c13df88f89c46654 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:43:01 +0100 Subject: [PATCH 1477/2509] 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 --- sound/pci/mixart/mixart_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 122c28efc48..f9860314613 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; } -- GitLab From b7a39bd0afc4021e8ad2b1189e884551e147427f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 18:38:49 +0100 Subject: [PATCH 1478/2509] 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 --- drivers/base/firmware_class.c | 2 +- include/linux/firmware.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 9fd4a853414..264b3a2cd86 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 6c7eff2ebad..88718d60153 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; -- GitLab From 5658c769443d543728b6c5c673dffc2df8676317 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 13:52:42 +0100 Subject: [PATCH 1479/2509] 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 --- drivers/base/firmware_class.c | 33 +++++++++++++++++++++++++++++-- include/asm-generic/vmlinux.lds.h | 7 +++++++ include/linux/firmware.h | 21 ++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 264b3a2cd86..b0be1d18fee 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 f054778e916..8d71a40625f 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 88718d60153..c8ecf5b2a20 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); -- GitLab From 4d2acfbfdf68257e846aaa355edd10fc35ba0feb Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 13:58:12 +0100 Subject: [PATCH 1480/2509] 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 --- Makefile | 2 +- drivers/base/Kconfig | 39 ++++++++++++++++++++ firmware/Makefile | 88 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 firmware/Makefile diff --git a/Makefile b/Makefile index 6315424a00b..f398cffa6c0 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 d7da109c24f..13cfcb435f7 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 00000000000..e69461f9362 --- /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 -- GitLab From d172e7f5c67f2d41f453c7aa83d3bdb405ef8ba5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 25 Jun 2008 13:56:07 +0100 Subject: [PATCH 1481/2509] 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 --- drivers/base/Kconfig | 25 +++++++++++++++++++++++++ firmware/Makefile | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 13cfcb435f7..d47482fa1d2 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 e69461f9362..cc25f5600d5 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-)))) -- GitLab From 88ecf814c47f577248751ddbe9626d98aeef5783 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 11:01:51 +0300 Subject: [PATCH 1482/2509] 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 --- Makefile | 13 ++++++++++++ firmware/Makefile | 24 +++++++++++++++------- scripts/Makefile.fwinst | 45 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 scripts/Makefile.fwinst diff --git a/Makefile b/Makefile index f398cffa6c0..bd2aa14f1e7 100644 --- a/Makefile +++ b/Makefile @@ -994,6 +994,16 @@ PHONY += depend dep 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 @@ -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 cc25f5600d5..3742feeb066 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 00000000000..1c030087037 --- /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: -- GitLab From bacfe09dd7545467965e8d8f1eab20bc62dce00d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 13:57:27 +0300 Subject: [PATCH 1483/2509] 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 --- include/linux/ihex.h | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 include/linux/ihex.h diff --git a/include/linux/ihex.h b/include/linux/ihex.h new file mode 100644 index 00000000000..df89edd890a --- /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__ */ -- GitLab From f1485f3deb89e6ae10c4d34662ec9e692855ab5d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 15:20:37 +0300 Subject: [PATCH 1484/2509] 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 --- include/linux/ihex.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/linux/ihex.h b/include/linux/ihex.h index df89edd890a..2baace2788a 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__ */ -- GitLab From 8bd6b2229bf98761465020467ec33547d05bff46 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 15:07:18 +0300 Subject: [PATCH 1485/2509] 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 --- firmware/Makefile | 14 +++ firmware/ihex2fw.c | 247 ++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.fwinst | 2 +- 3 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 firmware/ihex2fw.c diff --git a/firmware/Makefile b/firmware/Makefile index 3742feeb066..9e780a331e1 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 00000000000..9e77cd2f715 --- /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 1c030087037..3d2f4609578 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: -- GitLab From 59890f74e51abffd0dd017785d89f8a8475d489d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 26 Jun 2008 13:55:30 +0100 Subject: [PATCH 1486/2509] 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 --- firmware/Makefile | 7 ++++++ firmware/ihex2fw.c | 59 +++++++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 9e780a331e1..40881a96be0 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 9e77cd2f715..660b191ed75 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"); -- GitLab From 76770664dcbc008300c2ac8747671efcc4f78c2d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 26 May 2008 23:01:27 +0100 Subject: [PATCH 1487/2509] firmware: convert korg1212 driver to use firmware loader exclusively Signed-off-by: David Woodhouse --- firmware/Makefile | 1 + firmware/WHENCE | 19 + firmware/korg/k1212.dsp.ihex | 987 +++++++++++++++++++++++++ sound/pci/Kconfig | 10 - sound/pci/korg1212/korg1212-firmware.h | 987 ------------------------- sound/pci/korg1212/korg1212.c | 18 - 6 files changed, 1007 insertions(+), 1015 deletions(-) create mode 100644 firmware/WHENCE create mode 100644 firmware/korg/k1212.dsp.ihex delete mode 100644 sound/pci/korg1212/korg1212-firmware.h diff --git a/firmware/Makefile b/firmware/Makefile index 40881a96be0..ea4a883f5c6 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 00000000000..89ca95b9096 --- /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 00000000000..b151997b380 --- /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 7e474210957..1abbf877f20 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 f6f5b91806a..00000000000 --- 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 f4c85b52bde..4a44c0f20f7 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); -- GitLab From a292f404fabb342716a9d96e8155b7fb7b651dc1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 14:48:34 +0300 Subject: [PATCH 1488/2509] firmware: convert maestro3 driver to use firmware loader exclusively Signed-off-by: David Woodhouse --- firmware/Makefile | 2 + firmware/WHENCE | 14 ++ firmware/ess/maestro3_assp_kernel.fw.ihex | 120 +++++++++++++++ firmware/ess/maestro3_assp_minisrc.fw.ihex | 51 ++++++ sound/pci/Kconfig | 10 -- sound/pci/maestro3.c | 171 --------------------- 6 files changed, 187 insertions(+), 181 deletions(-) create mode 100644 firmware/ess/maestro3_assp_kernel.fw.ihex create mode 100644 firmware/ess/maestro3_assp_minisrc.fw.ihex diff --git a/firmware/Makefile b/firmware/Makefile index ea4a883f5c6..f312ac0e897 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 89ca95b9096..c08dbc887cb 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 00000000000..933c4c375c2 --- /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 00000000000..d2c0031dadf --- /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 1abbf877f20..32836ea4517 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 9dfba6eff85..b2582972c9a 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); } -- GitLab From 18ee6dfae89d9c131e3c9952939633ba8fa86247 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 15:07:34 +0300 Subject: [PATCH 1489/2509] firmware: convert ymfpci driver to use firmware loader exclusively Signed-off-by: David Woodhouse --- firmware/Makefile | 2 + firmware/WHENCE | 13 + firmware/yamaha/ds1_ctrl.fw.ihex | 769 ++++++++++++++ firmware/yamaha/ds1_dsp.fw.ihex | 9 + firmware/yamaha/ds1e_ctrl.fw.ihex | 769 ++++++++++++++ sound/pci/Kconfig | 10 - sound/pci/ymfpci/ymfpci_image.h | 1565 ----------------------------- sound/pci/ymfpci/ymfpci_main.c | 63 -- 8 files changed, 1562 insertions(+), 1638 deletions(-) create mode 100644 firmware/yamaha/ds1_ctrl.fw.ihex create mode 100644 firmware/yamaha/ds1_dsp.fw.ihex create mode 100644 firmware/yamaha/ds1e_ctrl.fw.ihex delete mode 100644 sound/pci/ymfpci/ymfpci_image.h diff --git a/firmware/Makefile b/firmware/Makefile index f312ac0e897..a962fe91e90 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 c08dbc887cb..ae40fb1c591 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 00000000000..aa9b1d7dcb0 --- /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 00000000000..acb0ba48f11 --- /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 00000000000..597f429ee31 --- /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 32836ea4517..e4a0045e2a3 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 112f2fff6c8..00000000000 --- 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 6298b29c66b..2164e34e46b 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; } -- GitLab From 0f805b86c9492c294c710de8539a8be68b521a86 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 16:39:16 +0300 Subject: [PATCH 1490/2509] smctr: use request_firmware() Signed-off-by: David Woodhouse --- drivers/net/tokenring/smctr.c | 56 +- drivers/net/tokenring/smctr.h | 2 - drivers/net/tokenring/smctr_firmware.h | 978 ------------------------- firmware/Makefile | 1 + firmware/WHENCE | 13 + firmware/tr_smctr.bin.ihex | 477 ++++++++++++ 6 files changed, 526 insertions(+), 1001 deletions(-) delete mode 100644 drivers/net/tokenring/smctr_firmware.h create mode 100644 firmware/tr_smctr.bin.ihex diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 5f1c5072b96..fa73e6eed6b 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 88dfa2e01d6..52df7dd815c 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 292e50ddf01..00000000000 --- 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 a962fe91e90..7a8fa9e1f46 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 ae40fb1c591..a8fc4b65859 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 00000000000..6797451ffa9 --- /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 -- GitLab From 79682499d9f3eaea4e6a970d8aa0b9bc1ac2a97f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 17:17:17 +0300 Subject: [PATCH 1491/2509] kaweth: use request_firmware() Signed-off-by: David Woodhouse --- drivers/net/usb/kaweth.c | 43 +- drivers/net/usb/kawethfw.h | 557 ---------------------- firmware/Makefile | 3 + firmware/WHENCE | 13 + firmware/kaweth/new_code.bin.ihex | 206 ++++++++ firmware/kaweth/new_code_fix.bin.ihex | 40 ++ firmware/kaweth/trigger_code.bin.ihex | 13 + firmware/kaweth/trigger_code_fix.bin.ihex | 3 + 8 files changed, 304 insertions(+), 574 deletions(-) delete mode 100644 drivers/net/usb/kawethfw.h create mode 100644 firmware/kaweth/new_code.bin.ihex create mode 100644 firmware/kaweth/new_code_fix.bin.ihex create mode 100644 firmware/kaweth/trigger_code.bin.ihex create mode 100644 firmware/kaweth/trigger_code_fix.bin.ihex diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 7c66b052f55..d6829db51b4 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 cf85fcb0d1a..00000000000 --- 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 7a8fa9e1f46..40939e91c83 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 a8fc4b65859..1373f529330 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 00000000000..292d40f4f33 --- /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 00000000000..fb35d3d0c92 --- /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 00000000000..c3e1658c280 --- /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 00000000000..7712f73faed --- /dev/null +++ b/firmware/kaweth/trigger_code_fix.bin.ihex @@ -0,0 +1,3 @@ +:10000000B6C3AABBCCDD0200060018003E0080008B +:060010009800AA000000A8 +:00000001FF -- GitLab From 0a2a736afa91e8a0402c9dbdaf2ee28481a50bd3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 19:50:06 +0300 Subject: [PATCH 1492/2509] ttusb-budget: use request_firmware() Signed-off-by: David Woodhouse Acked-by: Mauro Carvalho Chehab --- .../media/dvb/ttusb-budget/dvb-ttusb-budget.c | 16 +- .../dvb/ttusb-budget/dvb-ttusb-dspbootcode.h | 1644 ----------------- firmware/Makefile | 1 + firmware/WHENCE | 10 + firmware/ttusb-budget/dspbootcode.bin.ihex | 820 ++++++++ 5 files changed, 843 insertions(+), 1648 deletions(-) delete mode 100644 drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h create mode 100644 firmware/ttusb-budget/dspbootcode.bin.ihex diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 5d2d81ab237..bc2043e44eb 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 8c3cd545e8f..00000000000 --- 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 40939e91c83..be7e015719d 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 1373f529330..9c2a1ebf61a 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 00000000000..b4b2247077c --- /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 -- GitLab From 2971c579f93bcff26744672ea98c13bef71ded97 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 14:04:03 +0300 Subject: [PATCH 1493/2509] keyspan: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/serial/Kconfig | 24 +- drivers/usb/serial/keyspan.c | 78 ++-- drivers/usb/serial/keyspan.h | 84 ---- drivers/usb/serial/keyspan_mpr_fw.h | 286 -------------- drivers/usb/serial/keyspan_usa18x_fw.h | 447 --------------------- drivers/usb/serial/keyspan_usa19_fw.h | 285 -------------- drivers/usb/serial/keyspan_usa19qi_fw.h | 284 -------------- drivers/usb/serial/keyspan_usa19qw_fw.h | 448 --------------------- drivers/usb/serial/keyspan_usa19w_fw.h | 446 --------------------- drivers/usb/serial/keyspan_usa28_fw.h | 466 ---------------------- drivers/usb/serial/keyspan_usa28x_fw.h | 447 --------------------- drivers/usb/serial/keyspan_usa28xa_fw.h | 449 --------------------- drivers/usb/serial/keyspan_usa28xb_fw.h | 448 --------------------- drivers/usb/serial/keyspan_usa49w_fw.h | 464 ---------------------- drivers/usb/serial/keyspan_usa49wlc_fw.h | 476 ----------------------- firmware/Makefile | 19 + firmware/WHENCE | 39 ++ firmware/keyspan/mpr.HEX | 104 +++++ firmware/keyspan/usa18x.HEX | 141 +++++++ firmware/keyspan/usa19.HEX | 101 +++++ firmware/keyspan/usa19qi.HEX | 101 +++++ firmware/keyspan/usa19qw.HEX | 142 +++++++ firmware/keyspan/usa19w.HEX | 141 +++++++ firmware/keyspan/usa28.HEX | 148 +++++++ firmware/keyspan/usa28x.HEX | 141 +++++++ firmware/keyspan/usa28xa.HEX | 141 +++++++ firmware/keyspan/usa28xb.HEX | 142 +++++++ firmware/keyspan/usa49w.HEX | 145 +++++++ firmware/keyspan/usa49wlc.HEX | 153 ++++++++ 29 files changed, 1712 insertions(+), 5078 deletions(-) delete mode 100644 drivers/usb/serial/keyspan_mpr_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa18x_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa19_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa19qi_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa19qw_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa19w_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa28_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa28x_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa28xa_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa28xb_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa49w_fw.h delete mode 100644 drivers/usb/serial/keyspan_usa49wlc_fw.h create mode 100644 firmware/keyspan/mpr.HEX create mode 100644 firmware/keyspan/usa18x.HEX create mode 100644 firmware/keyspan/usa19.HEX create mode 100644 firmware/keyspan/usa19qi.HEX create mode 100644 firmware/keyspan/usa19qw.HEX create mode 100644 firmware/keyspan/usa19w.HEX create mode 100644 firmware/keyspan/usa28.HEX create mode 100644 firmware/keyspan/usa28x.HEX create mode 100644 firmware/keyspan/usa28xa.HEX create mode 100644 firmware/keyspan/usa28xb.HEX create mode 100644 firmware/keyspan/usa49w.HEX create mode 100644 firmware/keyspan/usa49wlc.HEX diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 9ba64ccc135..9a7681b5526 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 3df8a66c5c3..11e439b90ea 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 8d6ed0293bf..b52fb657a24 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 238805e91fb..00000000000 --- 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 e7b3bc00ce5..00000000000 --- 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 b023c523e12..00000000000 --- 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 1a264722609..00000000000 --- 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 0803f8b0bc3..00000000000 --- 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 75d6191245c..00000000000 --- 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 848b0a21f9e..00000000000 --- 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 3387ed9de4d..00000000000 --- 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 7b566781e2d..00000000000 --- 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 f5fcad44da3..00000000000 --- 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 dc24dace122..00000000000 --- 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 bef06a3350c..00000000000 --- 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 be7e015719d..db1b01a7a66 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 9c2a1ebf61a..d66291a78f0 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 00000000000..a53ba10b235 --- /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 00000000000..a9ff70eadfe --- /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 00000000000..c5d1496e871 --- /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 00000000000..353bfcfefb9 --- /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 00000000000..8a891023bf5 --- /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 00000000000..a3b84313f2c --- /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 00000000000..000c97863c0 --- /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 00000000000..9f0f7fac760 --- /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 00000000000..f14932efbaf --- /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 00000000000..07cb708f195 --- /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 00000000000..5e5b3d13dd5 --- /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 00000000000..8406eb1bf37 --- /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"; + -- GitLab From 3edbf98b863391bdd7ad2bf47b7db1689afac886 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 15:15:13 +0300 Subject: [PATCH 1494/2509] keyspan_pda: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/serial/keyspan_pda.c | 51 ++++----- drivers/usb/serial/keyspan_pda_fw.h | 99 ----------------- drivers/usb/serial/xircom_pgs_fw.h | 103 ------------------ firmware/Makefile | 2 + firmware/WHENCE | 14 +++ firmware/keyspan_pda/keyspan_pda.HEX | 83 ++++++++++++++ .../keyspan_pda}/keyspan_pda.S | 0 firmware/keyspan_pda/xircom_pgs.HEX | 87 +++++++++++++++ .../keyspan_pda}/xircom_pgs.S | 0 9 files changed, 210 insertions(+), 229 deletions(-) delete mode 100644 drivers/usb/serial/keyspan_pda_fw.h delete mode 100644 drivers/usb/serial/xircom_pgs_fw.h create mode 100644 firmware/keyspan_pda/keyspan_pda.HEX rename {drivers/usb/serial => firmware/keyspan_pda}/keyspan_pda.S (100%) create mode 100644 firmware/keyspan_pda/xircom_pgs.HEX rename {drivers/usb/serial => firmware/keyspan_pda}/xircom_pgs.S (100%) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ff54203944c..644a1eaaa37 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 f253accd231..00000000000 --- 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_fw.h b/drivers/usb/serial/xircom_pgs_fw.h deleted file mode 100644 index 3ff74a6d71a..00000000000 --- 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 db1b01a7a66..dd76fa5ab3f 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 d66291a78f0..b5be4bc8800 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 00000000000..6fcf02bb4b2 --- /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/drivers/usb/serial/keyspan_pda.S b/firmware/keyspan_pda/keyspan_pda.S similarity index 100% rename from drivers/usb/serial/keyspan_pda.S rename to firmware/keyspan_pda/keyspan_pda.S diff --git a/firmware/keyspan_pda/xircom_pgs.HEX b/firmware/keyspan_pda/xircom_pgs.HEX new file mode 100644 index 00000000000..e9b00d70282 --- /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/drivers/usb/serial/xircom_pgs.S b/firmware/keyspan_pda/xircom_pgs.S similarity index 100% rename from drivers/usb/serial/xircom_pgs.S rename to firmware/keyspan_pda/xircom_pgs.S -- GitLab From ae93a55bf948753de0bb8e43fa9c027f786abb05 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 16:19:39 +0300 Subject: [PATCH 1495/2509] emi26: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/misc/emi26.c | 96 +- drivers/usb/misc/emi26_fw.h | 5779 ---------------------------------- firmware/Makefile | 2 + firmware/WHENCE | 34 + firmware/emi26/bitstream.HEX | 4391 ++++++++++++++++++++++++++ firmware/emi26/firmware.HEX | 1261 ++++++++ firmware/emi26/loader.HEX | 116 + 7 files changed, 5870 insertions(+), 5809 deletions(-) delete mode 100644 drivers/usb/misc/emi26_fw.h create mode 100644 firmware/emi26/bitstream.HEX create mode 100644 firmware/emi26/firmware.HEX create mode 100644 firmware/emi26/loader.HEX diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 4b9dc81b845..4b994a0cd27 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 a47ff107ad9..00000000000 --- 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 dd76fa5ab3f..51ff1f35345 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 b5be4bc8800..a2f9390f317 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 00000000000..044d3f66438 --- /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 00000000000..1ca400eb141 --- /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 00000000000..77c439f6565 --- /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. + */ -- GitLab From b8e24bfabb03527d1c876fcaf24cccb05e1cbc65 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 17:35:47 +0300 Subject: [PATCH 1496/2509] emi62: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/misc/emi62.c | 130 +- drivers/usb/misc/emi62_fw_m.h | 8853 --------------------------------- drivers/usb/misc/emi62_fw_s.h | 8837 -------------------------------- firmware/Makefile | 2 + firmware/WHENCE | 23 + firmware/emi62/bitstream.HEX | 4372 ++++++++++++++++ firmware/emi62/loader.HEX | 107 + firmware/emi62/midi.HEX | 1266 +++++ firmware/emi62/spdif.HEX | 1257 +++++ 9 files changed, 7100 insertions(+), 17747 deletions(-) delete mode 100644 drivers/usb/misc/emi62_fw_m.h delete mode 100644 drivers/usb/misc/emi62_fw_s.h create mode 100644 firmware/emi62/bitstream.HEX create mode 100644 firmware/emi62/loader.HEX create mode 100644 firmware/emi62/midi.HEX create mode 100644 firmware/emi62/spdif.HEX diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 1a2b79ac5e1..20886c21e73 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 3567c900108..00000000000 --- 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 cef05e8517b..00000000000 --- 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 51ff1f35345..2b340746fa1 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 a2f9390f317..8e35d7bc7f6 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 00000000000..3c6ecc35eaa --- /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 00000000000..0edb2dc310e --- /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 00000000000..32a0d65176b --- /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 00000000000..322d50c9cf4 --- /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 +*/ -- GitLab From 5f24e2d6b40f0c74ce5bfaddfdb89f9bfae4b594 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 18:49:51 +0300 Subject: [PATCH 1497/2509] ti_usb_3410_5052: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/serial/ti_fw_3410.h | 885 -------------------------- drivers/usb/serial/ti_fw_5052.h | 885 -------------------------- drivers/usb/serial/ti_usb_3410_5052.c | 40 +- firmware/Makefile | 1 + firmware/WHENCE | 15 + firmware/ti_3410.fw.ihex | 862 +++++++++++++++++++++++++ firmware/ti_5052.fw.ihex | 862 +++++++++++++++++++++++++ 7 files changed, 1767 insertions(+), 1783 deletions(-) delete mode 100644 drivers/usb/serial/ti_fw_3410.h delete mode 100644 drivers/usb/serial/ti_fw_5052.h create mode 100644 firmware/ti_3410.fw.ihex create mode 100644 firmware/ti_5052.fw.ihex diff --git a/drivers/usb/serial/ti_fw_3410.h b/drivers/usb/serial/ti_fw_3410.h deleted file mode 100644 index 71e88579dfe..00000000000 --- 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 6ccf40a0979..00000000000 --- 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 a1c8aef0141..a26a629dfc4 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 2b340746fa1..28f975f2c9d 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 8e35d7bc7f6..205be9fec27 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 00000000000..b22c0425980 --- /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 00000000000..b529e07cd6e --- /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 -- GitLab From ec6752f5afce659025962e25fb2f42b3911254a1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 01:35:29 +0300 Subject: [PATCH 1498/2509] whiteheat: use request_firmware() Signed-off-by: David Woodhouse --- drivers/usb/serial/whiteheat.c | 77 +- drivers/usb/serial/whiteheat_fw.h | 1669 --------------------------- firmware/Makefile | 2 + firmware/WHENCE | 21 + firmware/whiteheat.HEX | 1097 ++++++++++++++++++ firmware/whiteheat_loader.HEX | 314 +++++ firmware/whiteheat_loader_debug.HEX | 403 +++++++ 7 files changed, 1887 insertions(+), 1696 deletions(-) delete mode 100644 drivers/usb/serial/whiteheat_fw.h create mode 100644 firmware/whiteheat.HEX create mode 100644 firmware/whiteheat_loader.HEX create mode 100644 firmware/whiteheat_loader_debug.HEX diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index f07e8a4c1f3..665aa77a917 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 8e0bdc746f9..00000000000 --- 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 28f975f2c9d..f937648aebc 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 205be9fec27..47ab241fd53 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 00000000000..8dae60295d5 --- /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 00000000000..5f663f6a284 --- /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 00000000000..5633d588613 --- /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" -- GitLab From 27d202fff1555f5b0eb16a5aedc452566f9ab8bb Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 5 Jun 2008 12:59:51 +0100 Subject: [PATCH 1499/2509] 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 --- drivers/atm/Makefile | 6 +- drivers/atm/ambassador.c | 140 +-- drivers/atm/ambassador.h | 11 - drivers/atm/atmsar11.data | 2063 ---------------------------------- drivers/atm/atmsar11.regions | 6 - drivers/atm/atmsar11.start | 4 - firmware/Makefile | 1 + firmware/atmsar11.HEX | 204 ++++ 8 files changed, 265 insertions(+), 2170 deletions(-) delete mode 100644 drivers/atm/atmsar11.data delete mode 100644 drivers/atm/atmsar11.regions delete mode 100644 drivers/atm/atmsar11.start create mode 100644 firmware/atmsar11.HEX diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index e4fa9965869..749266e955c 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 6adb72a2f87..703364b5217 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 df55fa8387d..bd1c46a7ef4 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 5dc8a7613f5..00000000000 --- 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 42252b7c0de..00000000000 --- 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 dba55e77d8f..00000000000 --- 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 f937648aebc..a561bdfb2ec 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 00000000000..dfddc190ac2 --- /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. -- GitLab From 547d8bb7ddf7f5d9f53741086a394c8318e15f16 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 11 Jun 2008 16:57:21 +0100 Subject: [PATCH 1500/2509] ip2: use request_firmware() Converted with help from Jaswinder Singh Signed-off-by: David Woodhouse Acked-by: Alan Cox --- drivers/char/ip2/fip_firm.h | 2149 -------------------------------- drivers/char/ip2/ip2base.c | 5 +- drivers/char/ip2/ip2main.c | 47 +- firmware/Makefile | 1 + firmware/WHENCE | 10 + firmware/intelliport2.bin.ihex | 2147 +++++++++++++++++++++++++++++++ 6 files changed, 2196 insertions(+), 2163 deletions(-) delete mode 100644 drivers/char/ip2/fip_firm.h create mode 100644 firmware/intelliport2.bin.ihex diff --git a/drivers/char/ip2/fip_firm.h b/drivers/char/ip2/fip_firm.h deleted file mode 100644 index 4c525fa4929..00000000000 --- 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 435ccfc7495..8155e247c04 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 c12cf8fc4be..e19df02ec86 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 a561bdfb2ec..2f81089dfd2 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 47ab241fd53..6c7b0b44712 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 00000000000..e9cfe8cb2b2 --- /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 */ -- GitLab From 0c5d5b70449eddb7e2c8a5fdaf71b6108c1a9afc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 10 Jul 2008 14:44:23 +0100 Subject: [PATCH 1501/2509] [ARM] 5171/1: ep93xx: fix compilation of modules using clocks Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- arch/arm/mach-ep93xx/clock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 9d7515c36bf..f62c35500bb 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); -- GitLab From 9cabcdbd4638cf884839ee4cd15780800c223b90 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 10 Jul 2008 15:54:12 +0100 Subject: [PATCH 1502/2509] [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 --- fs/gfs2/incore.h | 2 - fs/gfs2/ops_fstype.c | 1 - fs/gfs2/rgrp.c | 108 +++++-------------------------------------- 3 files changed, 12 insertions(+), 99 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 4b734c6e34f..4ab3c3a4a96 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 6ba69dd1a72..b4d1d649063 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 3401628d742..2d90fb25350 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; @@ -944,107 +939,30 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) return NULL; } -/** - * 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); -- GitLab From c9f6a6bbc284ba87337876086f7e2e6e0b0d50dd Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 10 Jul 2008 16:09:29 +0100 Subject: [PATCH 1503/2509] [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 --- fs/gfs2/incore.h | 1 - fs/gfs2/inode.c | 5 ----- fs/gfs2/ops_file.c | 19 ++----------------- fs/gfs2/super.c | 1 - fs/gfs2/sys.c | 2 -- 5 files changed, 2 insertions(+), 26 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 4ab3c3a4a96..448697a5c46 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 caf40908335..6da0ab355b8 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -789,12 +789,7 @@ 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 1737af98a42..21b397d0a29 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 12fe38fe498..63a8a902d9d 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 6f7e2e5858e..74846559fc3 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, }; -- GitLab From a93a6ce24215c69126c88f9c488afa50a168e0ca Mon Sep 17 00:00:00 2001 From: Li Xiaodong Date: Mon, 7 Jul 2008 18:04:09 +0800 Subject: [PATCH 1504/2509] [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 --- fs/gfs2/inode.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 04e9fef3f99..6074c2506f7 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, -- GitLab From 857f3fd7a496ddf4329345af65a4a2b16dd25fe8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Jul 2008 11:09:22 +0200 Subject: [PATCH 1505/2509] 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 --- kernel/time/tick-sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index cb75394ed00..86baa4f0dfe 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++; -- GitLab From 4abaca17e758e3326c96ced88b2cd9b7b84922f6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Jul 2008 14:39:56 +0100 Subject: [PATCH 1506/2509] [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 --- fs/gfs2/quota.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 56aaf915c59..3e073f5144f 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; -- GitLab From 007c05d4d2ce42fabd58cb54ed98e0a1714d9d86 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:09 -0400 Subject: [PATCH 1507/2509] 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 --- kernel/trace/trace_sched_switch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 93a66200915..cb817a209aa 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) -- GitLab From 001b6767b1d0c89e458e5ddb039245b268f569fb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:10 -0400 Subject: [PATCH 1508/2509] 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 --- kernel/trace/trace.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b8bd8800d0..df840f42be3 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, -- GitLab From 1e16c0a081f6c93f04c6af784d6a160955269f91 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:11 -0400 Subject: [PATCH 1509/2509] 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 --- kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/Makefile b/kernel/Makefile index ca2433e8487..480976275d9 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 -- GitLab From b5c21b4514b38f450848feb432f7120376d01ffe Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:12 -0400 Subject: [PATCH 1510/2509] 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 --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9ade79369bf..f8fdb9cedc2 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", -- GitLab From ad591240ceadcaf41b2a88855ca5f1c77c5a0298 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:13 -0400 Subject: [PATCH 1511/2509] 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 --- kernel/trace/trace_sched_wakeup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index bf7e91caef5..3c8d61df447 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", -- GitLab From 26bc83f4cb911a0b4dabfe23b700aaf3235f2955 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:14 -0400 Subject: [PATCH 1512/2509] 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 --- kernel/trace/trace_functions.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 7ee7dcd76b7..31214489797 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(); } -- GitLab From a2bb6a3d85ef3124cd336403a95abc0540d3fbe2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:15 -0400 Subject: [PATCH 1513/2509] 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 --- include/linux/ftrace.h | 1 + kernel/trace/ftrace.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 3121b95443d..f368d041e02 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 0f271c45cd0..1359632668a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1601,6 +1601,21 @@ core_initcall(ftrace_dynamic_init); # define ftrace_force_shutdown() do { } while (0) #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 * -- GitLab From 60bc080090e3bf6afa29c62cb25f913706551010 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:16 -0400 Subject: [PATCH 1514/2509] 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 --- kernel/trace/trace.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f8fdb9cedc2..2e37857f7df 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); -- GitLab From 62c43dd9864dbd52ff158922d1d08c75f20335af Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:50 -0400 Subject: [PATCH 1515/2509] 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 --- kernel/sched_clock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index ce05271219a..e383bc7df6d 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); -- GitLab From f7cce27f5605b9e137b829a47949cb2d3c7e1cab Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:51 -0400 Subject: [PATCH 1516/2509] 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 --- kernel/sched_clock.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index e383bc7df6d..42b81fa38cb 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) -- GitLab From af52a90a14cdaa54ecbfb6e6982abb13466a4b56 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:52 -0400 Subject: [PATCH 1517/2509] 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 --- include/linux/sched.h | 17 ++++++++++++++++- kernel/sched_clock.c | 39 ++++++++++++++++++++++++++++++++++++++- kernel/time/tick-sched.c | 2 ++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index c5d3f847ca8..33a8f42041f 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 42b81fa38cb..97159e225a7 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 b854a895591..d63008b09a4 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); /* -- GitLab From 2b8a0cf4890d7537a77b51caa8f508e4a05a0e67 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 19:49:41 -0400 Subject: [PATCH 1518/2509] 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 --- kernel/sched_clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 97159e225a7..55fca1e9e12 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 { -- GitLab From c0c87734f125d2fa8ebc70310f3257fa6209f2b6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:31 -0400 Subject: [PATCH 1519/2509] 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 --- kernel/sched_clock.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 55fca1e9e12..ee7cce5029c 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 -- GitLab From a83bc47c33ab182f1e48977fd5a04024d713c75e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:32 -0400 Subject: [PATCH 1520/2509] 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 --- kernel/sched_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index ee7cce5029c..28ff6bf5e02 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); -- GitLab From c300ba252829e9325e08f0af60687add94445b25 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:33 -0400 Subject: [PATCH 1521/2509] 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 --- kernel/sched_clock.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 28ff6bf5e02..8affbfd0cdb 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(); -- GitLab From b2613e370dbeb69edbff989382fa54f2395aa471 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 11 Jul 2008 16:44:27 +0200 Subject: [PATCH 1522/2509] 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 --- kernel/trace/ftrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1359632668a..4231a3dc224 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(); } -- GitLab From 0ce3a7e5bd305e96c924fab1e3126480c665f017 Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 11 Jul 2008 13:37:50 -0500 Subject: [PATCH 1523/2509] [SCSI] ipr: Fix HDIO_GET_IDENTITY oops for SATA devices Currently, ipr does not support HDIO_GET_IDENTITY to SATA devices. An oops occurs if userspace attempts to send the command. Since hald issues the command, ensure we fail the ioctl in ipr. This is a temporary solution to the oops. Once the ipr libata EH conversion is upstream, ipr will fully support HDIO_GET_IDENTITY. Tested-by: Milton Miller Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 999e91ea745..e7a3a655442 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -4913,8 +4914,11 @@ static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) struct ipr_resource_entry *res; res = (struct ipr_resource_entry *)sdev->hostdata; - if (res && ipr_is_gata(res)) + if (res && ipr_is_gata(res)) { + if (cmd == HDIO_GET_IDENTITY) + return -ENOTTY; return ata_scsi_ioctl(sdev, cmd, arg); + } return -EINVAL; } -- GitLab From feae1ef116ed381625d3731c5ae4f4ebcb3fa302 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 11 Jul 2008 13:54:40 -0700 Subject: [PATCH 1524/2509] 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 --- drivers/infiniband/core/user_mad.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 1fc17940a76..ef6dd825fee 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; } -- GitLab From 91ef4caf800030fa6e5224b8a41f8c74787b303d Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1525/2509] 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 --- fs/ext4/ext4.h | 1 + fs/ext4/ialloc.c | 9 +++++++++ fs/ext4/inode.c | 20 ++++++++++++++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8158083f7ac..f7a0758f468 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 c6efbab0c80..11cafe14aa2 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 8d970774641..269763b6636 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; /* -- GitLab From 71dc8fbcf5f6363342bd636a646eeac7cfef25c3 Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1526/2509] 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 --- fs/ext4/inode.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 269763b6636..7cce96a6935 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); } } -- GitLab From f3b35f063e9a795495fe2f7a2fe55fab11f8ab12 Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1527/2509] 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 --- fs/ext4/namei.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index ab16beaa830..384f1222602 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 */ -- GitLab From e7dfb2463e3c1b10c38372023e0186d25dec1fa6 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1528/2509] 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" --- fs/ext4/mballoc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c9900aade15..ba3aad27f44 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", -- GitLab From 8a35694e1181a5c6d6496dca09407fc7fa4c86c2 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1529/2509] 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" --- fs/ext4/ext4.h | 2 +- fs/ext4/ext4_i.h | 2 +- fs/ext4/ext4_sb.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f7a0758f468..ea8e4bc097c 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 26a4ae255d7..abf2744164e 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 5802e69f219..4de9a75ca6a 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 */ -- GitLab From ed8f9c751feb3aebf7c0dd25e61481a16412bd6e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1530/2509] 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" --- fs/ext4/mballoc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index ba3aad27f44..bdb9f299157 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; -- GitLab From 07d45f126712fea3a9f44068bf65e0a26a162286 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1531/2509] 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" --- fs/ext4/balloc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 9cc80b9cc8d..c29d774abe5 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__) -- GitLab From 91d99827791fdd5f9424458ad5ae870f89dbcadf Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1532/2509] ext4: switch to seq_files Signed-off-by: Alexey Dobriyan Cc: Mingming Cao Signed-off-by: "Theodore Ts'o" Signed-off-by: Andrew Morton --- fs/ext4/mballoc.c | 68 +++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index bdb9f299157..6280ad3829d 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) -- GitLab From 69baee062a044ef1588e423e52131710e7584d1a Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1533/2509] 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" --- fs/ext4/dir.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 2bf0331ea19..5ed5108766c 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; -- GitLab From 31b481dc7c249eac0a108ec5dfc0d4aef2217e39 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1534/2509] 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" --- fs/ext4/mballoc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6280ad3829d..d429014071c 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; -- GitLab From fdf6c7a7683c6272e953a33358920e98a4d93cf0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1535/2509] 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" --- fs/ext4/mballoc.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index d429014071c..b64600be206 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) -- GitLab From 74767c5a2dca0a60676d60d36377a41f60ca42ba Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1536/2509] 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" --- fs/ext4/mballoc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b64600be206..6d69dd92aad 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); -- GitLab From 3537576a707c6df98e883b77b854c6083f844602 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1537/2509] 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" --- fs/ext4/xattr_trusted.c | 4 +--- fs/ext4/xattr_user.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index fff33382cad..ac1a52cf2a3 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 67be723fcc4..d91aa61b42a 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)) -- GitLab From 574ca174c97f790086e3e6f2251381420ad38fd0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1538/2509] 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" --- fs/ext4/balloc.c | 12 ++++++------ fs/ext4/group.h | 2 +- fs/ext4/ialloc.c | 2 +- fs/ext4/mballoc.c | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index c29d774abe5..ba411233cc2 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 7eb0604e7ee..c2c0a8d06d0 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 11cafe14aa2..b30cc79b9fc 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 6d69dd92aad..21ee6d42ee7 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); -- GitLab From 7ad72ca60b6be3c79f90a81ce5883e12a2c6e667 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1539/2509] ext4: Remove unused variable from ext4_show_options Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 02bf2434397..588cfb40864 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); -- GitLab From f795e1407343ebe6597653f4a6a7f770676e84c5 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1540/2509] 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" --- fs/ext4/namei.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 384f1222602..c7bf01261c7 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -182,6 +182,16 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, 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. @@ -553,15 +563,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 -- GitLab From cfbe7e4f5e4a0e1fc2ff23b167bfb3fa992f623d Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Sun, 13 Jul 2008 21:03:31 -0400 Subject: [PATCH 1541/2509] 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 --- fs/ext4/mballoc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 21ee6d42ee7..771a1d60852 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); -- GitLab From 7e5a8cdd843b7af8d6d38a9bf96306145edb66e0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Sun, 13 Jul 2008 21:03:31 -0400 Subject: [PATCH 1542/2509] 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 --- fs/ext4/mballoc.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 771a1d60852..b882868f466 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)); -- GitLab From 4db9c54a53135b7c1c1f403f1aeaf9fc0d7738b8 Mon Sep 17 00:00:00 2001 From: Stoyan Gaydarov Date: Sun, 13 Jul 2008 21:03:29 -0400 Subject: [PATCH 1543/2509] 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 --- fs/ext4/ext4.h | 4 ++-- fs/ext4/ext4_jbd2.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ea8e4bc097c..109c7d4c19a 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 9255a7d28b2..d0aa9ee20f8 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) { -- GitLab From 736603ab297506f4396cb5af592004499950fcfd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1544/2509] 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" --- fs/jbd2/commit.c | 3 +++ include/linux/jbd2.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index a2ed72f7cee..92b6ac3df8a 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 d147f0f9036..ec9cadf5822 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; }; /* -- GitLab From 772cb7c83ba256a11c7bf99a11bef3858d23767c Mon Sep 17 00:00:00 2001 From: "Jose R. Santos" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1545/2509] 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" --- fs/ext4/balloc.c | 14 +++++++ fs/ext4/ext4.h | 25 +++++++++++- fs/ext4/ext4_sb.h | 3 ++ fs/ext4/ialloc.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/mballoc.c | 15 ++++++++ fs/ext4/super.c | 57 ++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 1 deletion(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index ba411233cc2..0b2b7549ac6 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 109c7d4c19a..0bfeae18f1a 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 4de9a75ca6a..6300226d553 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 b30cc79b9fc..8b0a10acd70 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 b882868f466..5dcb826401b 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 588cfb40864..b9ad3d85206 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); -- GitLab From 530576bbf379fc45cfb34f246257d8526db44567 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Sun, 13 Jul 2008 21:06:39 -0400 Subject: [PATCH 1546/2509] 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" --- fs/jbd2/transaction.c | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index d6e006e6780..ba620c4493d 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; } -- GitLab From f9a8ac99fd79eb961a8573ccf058439bc17b4d3a Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1547/2509] 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" --- fs/ext4/super.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b9ad3d85206..6c80f37433e 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. -- GitLab From 363d4251d4bd984c304e0989789f6494343660fd Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1548/2509] 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" --- fs/ext4/mballoc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 5dcb826401b..cde232bdaed 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, -- GitLab From a379cd1d6bb00f9f5d2759d4a5621a884df5914e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1549/2509] 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" --- fs/ext4/extents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 47929c4e3da..f7a746b5b7b 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 */ -- GitLab From 787e0981fad97a5ca3d07c7afe115a7e345b2861 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1550/2509] 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" --- fs/ext4/extents.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f7a746b5b7b..bc17ed74284 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); -- GitLab From 1973adcba570c226de840299056e055a3614185e Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1551/2509] 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" --- fs/ext4/extents.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc17ed74284..3e966daaade 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); -- GitLab From 9102e4fa8016af8bf1a263df913ee8fdafd4dfb0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1552/2509] 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" --- fs/ext4/extents.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3e966daaade..17ea8bb12aa 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) -- GitLab From d9c769b769a8bcd70371c71797fc4e407b37ba75 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1553/2509] 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" --- fs/ext4/namei.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c7bf01261c7..387ad98350c 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); } /* -- GitLab From 7477827f6686ce29b6216d9eb26f6b9027742dcc Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1554/2509] ext4: Fix sparse warning Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/balloc.c | 2 +- fs/ext4/super.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 0b2b7549ac6..6dcbec9b256 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 6c80f37433e..80f06159ee9 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; -- GitLab From 6afd670713c9e7d5c5550e379dfedca8ffab4c90 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1555/2509] 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 --- fs/ext4/balloc.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6dcbec9b256..1327ac3a04d 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) { -- GitLab From 7061eba75ceb0835ba61e7cbd757a6f9c1e4af92 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1556/2509] 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" --- fs/ext4/balloc.c | 36 ++++++++++++++++++++++-- fs/ext4/ext4.h | 7 +++-- fs/ext4/extents.c | 2 +- fs/ext4/inode.c | 72 +++++++++++++++++++++++++++++++++++------------ fs/ext4/xattr.c | 2 +- 5 files changed, 95 insertions(+), 24 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 1327ac3a04d..816f1dbaeb3 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 0bfeae18f1a..d44a7fb6a7b 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 17ea8bb12aa..c729b3507b4 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 7cce96a6935..bc950562b5b 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 ff08633f398..93c5fdcdad2 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; -- GitLab From 654b4908bc17a6318d18f3036fecc5155de92f55 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1557/2509] 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" --- fs/ext4/balloc.c | 127 +++++++++++++++++++++++++++------------------- fs/ext4/ext4.h | 2 +- fs/ext4/extents.c | 10 ++-- fs/ext4/inode.c | 2 +- fs/ext4/mballoc.c | 2 +- 5 files changed, 84 insertions(+), 59 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 816f1dbaeb3..48787e86d43 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 d44a7fb6a7b..e622ade69d5 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 c729b3507b4..555155d239d 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 bc950562b5b..c5d506dce8c 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 cde232bdaed..816ba8cce79 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; } -- GitLab From d755fb384250d6bd7fd18a0930e71965acc8e72e Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1558/2509] 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" --- fs/ext4/fsync.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 1c8ba48d4f8..a45c3737ad3 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; -- GitLab From 07031431072ece801d53d2c03d5e5bb21f4f64a4 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1559/2509] 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" --- fs/ext4/balloc.c | 51 ++++++++++++++++++++++++++++++----------------- fs/ext4/ext4.h | 2 ++ fs/ext4/mballoc.c | 7 ++++++- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 48787e86d43..25f63d8c1b3 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 e622ade69d5..2c4b48519c8 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 816ba8cce79..1666ac184e3 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: -- GitLab From 47b4a50bebfd34b5e1fa2a9c673c8f31fa231cc1 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1560/2509] 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" --- fs/ext4/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 80f06159ee9..1b330cd71ca 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); -- GitLab From 953e622b601f58b7cc0f29fe644457fa40a18456 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1561/2509] 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" --- fs/ext4/extents.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 555155d239d..bb36a28f8ff 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: -- GitLab From 5f21b0e642d7bf6fe4434c9ba12bc9cb96b17cf7 Mon Sep 17 00:00:00 2001 From: Frederic Bohe Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1562/2509] 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 --- fs/ext4/ext4.h | 4 + fs/ext4/mballoc.c | 234 +++++++++++++++++++++++++++++++++++----------- fs/ext4/resize.c | 52 ++++++++++- 3 files changed, 234 insertions(+), 56 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2c4b48519c8..64edb09c481 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 1666ac184e3..8d254ca83d9 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 9ff7b1c0423..f000fbe2cd9 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -865,6 +865,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); 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, @@ -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)); -- GitLab From 93e3270c87549dc531a0b0e5d06362d998d810cb Mon Sep 17 00:00:00 2001 From: "Jose R. Santos" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1563/2509] 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" --- Documentation/filesystems/ext4.txt | 106 +++++++++++++++++------------ 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 0c5086db835..7e940c64be4 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 -- GitLab From 2e9ee850355593e311d9a26542290fe51e152f74 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1564/2509] 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" --- fs/ext4/ext4.h | 1 + fs/ext4/file.c | 19 ++++++++++++++- fs/ext4/inode.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 64edb09c481..98760d14e2c 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 4159be6366a..b9510ba66a2 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 c5d506dce8c..034fc544aa6 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; +} -- GitLab From c7d206b3379f7d6462e778b74f475c470ee3dcaf Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1565/2509] 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" --- fs/buffer.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/buffer.c b/fs/buffer.c index 0f51c0f7c26..f4b033237a0 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); -- GitLab From cf108bca465dde0c015f32dd453b99457d31c7c7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1566/2509] 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" --- fs/ext4/ext4.h | 4 +- fs/ext4/extents.c | 15 +-- fs/ext4/inode.c | 292 +++++++++++++++++++++++----------------------- 3 files changed, 155 insertions(+), 156 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 98760d14e2c..f65829bbe7a 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 bb36a28f8ff..b722bce7d66 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 034fc544aa6..320acb6c35b 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); } @@ -1290,29 +1291,6 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh) return ext4_journal_dirty_metadata(handle, 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) -- GitLab From 9ddfc3dc75b5cc55ff3cfa586e962d252f1db9d3 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1567/2509] 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" --- fs/ext4/extents.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b722bce7d66..7844bbb2bac 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); -- GitLab From f4c0a0fdfae708f7aa438c27a380ed4071294e11 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1568/2509] 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 --- include/linux/fs.h | 2 ++ mm/filemap.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index d8e2762ed14..97f992adc62 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 1e6a7d34874..65d9d9e2b75 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 -- GitLab From c851ed540173736e60d48b53b91a16ea5c903896 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1569/2509] 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 --- fs/jbd2/commit.c | 90 +++++++++++++++++++++++++++++++++++++++++++ fs/jbd2/journal.c | 52 +++++++++++++++++++++++++ fs/jbd2/transaction.c | 86 +++++++++++++++++++++++++++++++++++++++++ include/linux/jbd2.h | 42 ++++++++++++++++++++ 4 files changed, 270 insertions(+) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 92b6ac3df8a..3ca107b5c86 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 2e24567c4a7..78cf7bd7f60 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); @@ -2194,6 +2198,54 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) jbd_unlock_bh_journal_head(bh); } +/* + * 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 */ diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index ba620c4493d..98b596d2370 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 ec9cadf5822..622c3d8ca4e 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; /** @@ -566,6 +598,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 */ @@ -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 -- GitLab From 678aaf481496b01473b778685eca231d6784098b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1570/2509] 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" --- fs/ext4/ext4_i.h | 1 + fs/ext4/ext4_jbd2.h | 7 +- fs/ext4/inode.c | 158 ++++++++++++++------------------------------ fs/ext4/super.c | 5 +- 4 files changed, 59 insertions(+), 112 deletions(-) diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h index abf2744164e..c2903ef7215 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 d0aa9ee20f8..eb8bc3afe6e 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 320acb6c35b..7b9569179fd 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 1b330cd71ca..629d0fa27e3 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); -- GitLab From 87c89c232c8f7b3820c33c3b9bc803e9358027da Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1571/2509] jbd2: Remove data=ordered mode support using jbd buffer heads Signed-off-by: Jan Kara --- fs/jbd2/checkpoint.c | 1 - fs/jbd2/commit.c | 221 ++---------------------------------------- fs/jbd2/journal.c | 1 - fs/jbd2/transaction.c | 217 ++--------------------------------------- include/linux/jbd2.h | 29 ++---- 5 files changed, 21 insertions(+), 448 deletions(-) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 6914598022c..91389c8aee8 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 3ca107b5c86..483183d15ed 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 @@ -79,21 +79,6 @@ nope: __brelse(bh); } -/* - * 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 @@ -199,162 +184,6 @@ static int journal_wait_on_commit_record(struct buffer_head *bh) return ret; } -/* - * 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,24 +431,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 = 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); @@ -627,16 +439,6 @@ void jbd2_journal_commit_transaction(journal_t *journal) 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 @@ -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 78cf7bd7f60..b26c6d9fe6a 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 98b596d2370..4f7cadbb19f 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -942,183 +942,6 @@ out: return err; } -/** - * 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. @@ -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 622c3d8ca4e..3dd20900709 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -542,24 +542,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) @@ -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); -- GitLab From 29a814d2ee0e43c2980f33f91c1311ec06c0aa35 Mon Sep 17 00:00:00 2001 From: Alex Tomas Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1572/2509] 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" --- fs/buffer.c | 7 +++++-- fs/mpage.c | 14 +++++--------- include/linux/mpage.h | 10 ++++++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index f4b033237a0..5fa1512cd9a 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 235e4d3873a..dbcc7af76a1 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 068a0c9946a..5c42821da2d 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, -- GitLab From 64769240bd07f446f83660bb143bb609d8ab4910 Mon Sep 17 00:00:00 2001 From: Alex Tomas Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1573/2509] 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 --- fs/ext4/ext4.h | 1 + fs/ext4/inode.c | 699 +++++++++++++++++++++++++++++++++++++++++++++++- fs/ext4/super.c | 6 +- 3 files changed, 700 insertions(+), 6 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f65829bbe7a..ee9576dc0ba 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 7b9569179fd..2bef4f879e4 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. */ @@ -1407,6 +1410,669 @@ static int ext4_journalled_write_end(struct file *file, return ret ? ret : copied; } +/* + * 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 629d0fa27e3..de9d3d0eb20 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\" " -- GitLab From e8ced39d5e8911c662d4d69a342b9d053eaaac4e Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1574/2509] 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" --- fs/ext4/balloc.c | 2 +- include/linux/percpu_counter.h | 12 +++++++++--- lib/percpu_counter.c | 7 ++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 25f63d8c1b3..6369bacf0dc 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 9007ccdfc11..20838883535 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 119174494cb..4a8ba4bf5f6 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; } -- GitLab From d2a1763791a634e315ec926b62829c1e88842c86 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Mon, 14 Jul 2008 17:52:37 -0400 Subject: [PATCH 1575/2509] 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 --- fs/ext4/balloc.c | 49 +++++++---- fs/ext4/dir.c | 3 +- fs/ext4/ext4.h | 6 +- fs/ext4/ext4_extents.h | 1 + fs/ext4/ext4_i.h | 7 ++ fs/ext4/extents.c | 32 ++++++- fs/ext4/inode.c | 184 ++++++++++++++++++++++++++++++++++------- fs/ext4/mballoc.c | 20 ++++- fs/ext4/super.c | 5 ++ 9 files changed, 257 insertions(+), 50 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6369bacf0dc..495ab21b983 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 5ed5108766c..d3d23d73c08 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 ee9576dc0ba..0962f4e2657 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 75333b595fa..6c166c0a54b 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 c2903ef7215..ef7409f0e7e 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 7844bbb2bac..dabc3b68d24 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 2bef4f879e4..a6b800c5847 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 8d254ca83d9..8d141a25bbe 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 de9d3d0eb20..25e2f2488cd 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; } -- GitLab From 06d6cf6959d22037fcec598f4f954db5db3d7356 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1576/2509] 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" --- include/linux/writeback.h | 1 + mm/page-writeback.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f462439cc28..0d8573e6b9e 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 789b6adbef3..ded57d52806 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); -- GitLab From 61628a3f3a37af2bf25daf8e26fd6b76a78c4f76 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1577/2509] 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" --- fs/ext4/extents.c | 10 ++- fs/ext4/inode.c | 201 +++++++++++++++++++++++++++++++++------------- 2 files changed, 152 insertions(+), 59 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index dabc3b68d24..42c4c0c892e 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 a6b800c5847..7923336ecf9 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, -- GitLab From cd1aac32923a9c8adcc0ae85e33c1ca0c5855838 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1578/2509] 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" --- fs/ext4/inode.c | 30 +++++++++++++++++++++++++----- fs/jbd2/commit.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7923336ecf9..24518b57733 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 483183d15ed..f8b3be87322 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. @@ -184,6 +186,27 @@ static int journal_wait_on_commit_record(struct buffer_head *bh) return ret; } +/* + * 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); -- GitLab From f0e6c98593eb8a77edb7dd0edb22bb9f9368c567 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1579/2509] 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" --- fs/ext4/inode.c | 169 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 45 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 24518b57733..ce47847bb37 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); -- GitLab From 632eaeab1feb5d78c1e2bfb1d2dfc0ebb8ac187f Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1580/2509] 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" --- fs/ext4/inode.c | 63 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ce47847bb37..0fbe678d40b 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; @@ -3393,6 +3425,11 @@ void ext4_truncate(struct inode *inode) if (ext4_orphan_add(handle, 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 @@ -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); -- GitLab From 3e3398a08d6e516675d5af853d625dc7dd90eab1 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1581/2509] 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" --- fs/ext4/ext4.h | 2 ++ fs/ext4/file.c | 1 + fs/ext4/inode.c | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0962f4e2657..303e41cf7b1 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 b9510ba66a2..430eb7978db 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 0fbe678d40b..8ca2763df09 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()? -- GitLab From dd919b9822c5fd9fd72f95a602440130297c3857 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1582/2509] 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 --- fs/ext4/super.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 25e2f2488cd..4e104dd0ec2 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); -- GitLab From c07651b556323e0e763c452587fe29d2b034b314 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1583/2509] 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" --- fs/ext4/super.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4e104dd0ec2..2bf9cdd7a03 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: -- GitLab From e4079a11f5ed966b7d972cc69e8d337a0f095e32 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1584/2509] 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" --- fs/ext4/ialloc.c | 6 +----- fs/ext4/super.c | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 8b0a10acd70..a92eb305344 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 2bf9cdd7a03..1cb371dcd60 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); -- GitLab From 49f1487b2e41bd8439ea39a4f15b4064e823cc54 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: [PATCH 1585/2509] 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" --- Documentation/filesystems/ext4.txt | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 7e940c64be4..80e193d82e2 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 ========== -- GitLab From 38032f72601deac7aab00691c79e83d09b204e2a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 11 Jul 2008 12:57:31 -0700 Subject: [PATCH 1586/2509] 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 --- drivers/clocksource/acpi_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 3baee020afc..bcd7d0e429e 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; -- GitLab From de32a2434f7ce4600da90ecb44abcdc365ada1d0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 12 Jul 2008 05:33:30 +0200 Subject: [PATCH 1587/2509] kernel-paramaters: document pmtmr= command line option Signed-off-by: Thomas Gleixner --- Documentation/kernel-parameters.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e07c432c731..356b64ba706 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 } -- GitLab From 5ac37f87ff18843aabab84cf75b2f8504c2d81fe Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Fri, 11 Jul 2008 18:04:46 +0200 Subject: [PATCH 1588/2509] x86: fix ldt limit for 64 bit Fix size of LDT entries. On x86-64, ldt_desc is a double-sized descriptor. Signed-off-by: Michael Karcher Signed-off-by: Ingo Molnar --- include/asm-x86/desc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 268a012bcd7..28bddbcb38b 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -192,8 +192,8 @@ static inline void native_set_ldt(const void *addr, unsigned int entries) unsigned cpu = smp_processor_id(); ldt_desc ldt; - set_tssldt_descriptor(&ldt, (unsigned long)addr, - DESC_LDT, entries * sizeof(ldt) - 1); + set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT, + entries * LDT_ENTRY_SIZE - 1); write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, &ldt, DESC_LDT); asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); -- GitLab From a72f0dbfd93159acdf2467e5a022b28f763061f6 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Sat, 12 Jul 2008 15:42:11 +0800 Subject: [PATCH 1589/2509] 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 --- arch/s390/crypto/crypt_s390.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 9992f95ef99..0ef9829f2ad 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); -- GitLab From 27898988174bb211fd962ea73b9c6dc09f888705 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 10 Jul 2008 22:10:55 -0500 Subject: [PATCH 1590/2509] [SCSI] fusion: default MSI to disabled for SPI and FC controllers There's a fault on the FC controllers that makes them not respond correctly to MSI. The SPI controllers are fine, but are likely to be onboard on older motherboards which don't handle MSI correctly, so default both these cases to disabled. Enable by setting the module parameter mpt_msi_enable=1. For the SAS case, enable MSI by default, but it can be disabled by setting the module parameter mpt_msi_enable=0. Cc: "Prakash, Sathya" Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index db3c892f87f..d40d6d15ae2 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1686,9 +1686,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->bus_type = SAS; } - if (ioc->bus_type == SAS && mpt_msi_enable == -1) - ioc->msi_enable = 1; - else + if (mpt_msi_enable == -1) { + /* Enable on SAS, disable on FC and SPI */ + if (ioc->bus_type == SAS) + ioc->msi_enable = 1; + else + ioc->msi_enable = 0; + } else + /* follow flag: 0 - disable; 1 - enable */ ioc->msi_enable = mpt_msi_enable; if (ioc->errata_flag_1064) -- GitLab From cc4724492ddf920475ad7f12bfcb81ffca16f777 Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Wed, 21 May 2008 01:01:11 +0530 Subject: [PATCH 1591/2509] [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 --- drivers/message/fusion/mptspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 1cdea1aaa07..9b49516cf5a 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; -- GitLab From d54d48b80fb523ce1b1a644e4876b08835ad757f Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Wed, 21 May 2008 01:02:18 +0530 Subject: [PATCH 1592/2509] [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 --- drivers/message/fusion/mptbase.c | 86 ++++++++++++++++++++++++++++++++ drivers/message/fusion/mptbase.h | 8 +++ 2 files changed, 94 insertions(+) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 30a800effe5..9bc35617b87 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 7496793db2c..6adab648dbb 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; /* -- GitLab From 40753caa364bfba60ebd5e2a8bdf366ef175d03c Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:56 -0500 Subject: [PATCH 1593/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 1 + drivers/scsi/iscsi_tcp.c | 5 +-- drivers/scsi/scsi_transport_iscsi.c | 46 +++++++++++++++++++----- include/scsi/iscsi_if.h | 7 ++++ include/scsi/libiscsi.h | 1 + include/scsi/scsi_transport_iscsi.h | 4 +-- 6 files changed, 51 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index aeb58cae9a3..efc121986c5 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 72b9b2a0eba..81c421a7d47 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 65d1737eb66..2a6669d967c 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 e19e5842316..1883c85cd3e 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 cd3ca63d4fb..f24cf024673 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 aab1eae2ec4..02a852000be 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); -- GitLab From d3826721b198001c55353b1c54e10843068aae63 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:57 -0500 Subject: [PATCH 1594/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 1 - drivers/infiniband/ulp/iser/iscsi_iser.h | 1 - drivers/scsi/iscsi_tcp.c | 2 -- drivers/scsi/libiscsi.c | 2 +- drivers/scsi/scsi_transport_iscsi.c | 4 ---- include/scsi/scsi_transport_iscsi.h | 2 -- 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index efc121986c5..32f5d5e79ab 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 a8c1b300e34..66a2f30ada0 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 81c421a7d47..aecadbdce9d 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 b43bf1d60da..01a1a4d36f2 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 2a6669d967c..e6a090e9c8a 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 02a852000be..afed70ec2aa 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); -- GitLab From 32c6e1b9a2e27076b7070a9ec56a9e5437ebd725 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:58 -0500 Subject: [PATCH 1595/2509] [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 --- drivers/scsi/scsi_transport_iscsi.c | 24 +++++++++++------------- include/scsi/scsi_transport_iscsi.h | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index e6a090e9c8a..5577a60bec4 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 afed70ec2aa..728702292a8 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; -- GitLab From 756135215ec743be6fdce2bdebe8cdb9f8a231f6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:59 -0500 Subject: [PATCH 1596/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 74 +++++--- drivers/scsi/iscsi_tcp.c | 102 ++++++----- drivers/scsi/libiscsi.c | 213 ++++++++++------------- drivers/scsi/qla4xxx/ql4_os.c | 1 - drivers/scsi/scsi_transport_iscsi.c | 5 +- include/scsi/iscsi_if.h | 7 - include/scsi/libiscsi.h | 31 ++-- include/scsi/scsi_transport_iscsi.h | 8 +- 8 files changed, 225 insertions(+), 216 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 32f5d5e79ab..5a750042e2b 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 aecadbdce9d..8cdcaf33fb4 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 01a1a4d36f2..64b1dd82736 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 0c786944d2c..6c6ee0f3499 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 5577a60bec4..9c00a157b48 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 1883c85cd3e..801a677777c 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 f24cf024673..8a6271c2093 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 728702292a8..702eda2904d 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); -- GitLab From a4804cd6eb19318ae8d08ea967cfeaaf5c5b68a6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:00 -0500 Subject: [PATCH 1597/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 17 +++---- drivers/scsi/iscsi_tcp.c | 18 +++---- drivers/scsi/libiscsi.c | 60 +++++++++++++++++++++--- drivers/scsi/scsi_transport_iscsi.c | 20 ++++++++ include/scsi/libiscsi.h | 11 ++++- include/scsi/scsi_transport_iscsi.h | 4 ++ 6 files changed, 99 insertions(+), 31 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 5a750042e2b..62e35e503e4 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 8cdcaf33fb4..e19d92f2d75 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 64b1dd82736..73c37c04ca6 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 9c00a157b48..6fdaa2ee663 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 8a6271c2093..9a26d715a95 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 702eda2904d..761f62da7cc 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 */ -- GitLab From 5d91e209fb21fb9cc765729d4c6a85a9fb6c9187 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:01 -0500 Subject: [PATCH 1598/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 16 +++------------- drivers/scsi/iscsi_tcp.c | 19 +++++-------------- drivers/scsi/libiscsi.c | 15 ++++++++++----- drivers/scsi/qla4xxx/ql4_os.c | 7 +++---- drivers/scsi/scsi_transport_iscsi.c | 24 ++++++++++++------------ include/scsi/libiscsi.h | 8 ++++---- include/scsi/scsi_transport_iscsi.h | 9 +++------ 7 files changed, 40 insertions(+), 58 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 62e35e503e4..9b34946eb00 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 e19d92f2d75..dfaf9fa5734 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 73c37c04ca6..784a935fad4 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 6c6ee0f3499..5822dd59582 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 6fdaa2ee663..6b8516a0970 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 9a26d715a95..4e1c14f20dd 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 761f62da7cc..4028f121d54 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); -- GitLab From 5af3e91d232b7e022f258202f72ebb79b8b0c706 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:02 -0500 Subject: [PATCH 1599/2509] [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 --- include/scsi/libiscsi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 4e1c14f20dd..f54aeb1e8ae 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 -- GitLab From b40977d95fb3a1898ace6a7d97e4ed1a33a440a4 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:03 -0500 Subject: [PATCH 1600/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 42 ++++++++++++++++++++++-- drivers/infiniband/ulp/iser/iscsi_iser.h | 5 +++ drivers/infiniband/ulp/iser/iser_verbs.c | 14 +++++++- drivers/scsi/libiscsi.c | 3 +- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 9b34946eb00..8a1bfb7277c 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 66a2f30ada0..bd5c1a554ea 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 d19cfe605eb..5daed2bd710 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 784a935fad4..79bc49fd7f1 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) { -- GitLab From 0af967f5d4f2dd1e00618d34ac988037d37a6c3b Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:04 -0500 Subject: [PATCH 1601/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 8 +-- drivers/infiniband/ulp/iser/iser_initiator.c | 23 ++++---- drivers/scsi/iscsi_tcp.c | 13 +++-- drivers/scsi/libiscsi.c | 60 ++++++++++++++------ include/scsi/libiscsi.h | 4 +- 5 files changed, 65 insertions(+), 43 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 8a1bfb7277c..7b146886906 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 08dc81c46f4..b82a5f2d4d3 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 dfaf9fa5734..f2a08f7ed90 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 79bc49fd7f1..4bc63c4b3c1 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 f54aeb1e8ae..9be6a70faff 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); -- GitLab From 052d014485d2ce5bb7fa8dd0df875dafd1db77df Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:05 -0500 Subject: [PATCH 1602/2509] [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 --- drivers/scsi/libiscsi.c | 179 +++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4bc63c4b3c1..1e605de07cf 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) -- GitLab From 3e5c28ad0391389959ccae81c938c7533efb3490 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:06 -0500 Subject: [PATCH 1603/2509] [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 --- drivers/scsi/libiscsi.c | 518 +++++++++++++--------------- include/scsi/libiscsi.h | 29 +- include/scsi/scsi_transport_iscsi.h | 41 +-- 3 files changed, 272 insertions(+), 316 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1e605de07cf..ef92b1b0f16 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 9be6a70faff..d1c36759b35 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 4028f121d54..3f24503dfdf 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); -- GitLab From fbc514b4e262bc0596faae8640ebc0b9142a1cdd Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:07 -0500 Subject: [PATCH 1604/2509] [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 --- drivers/scsi/iscsi_tcp.c | 130 ++++++++++++++++----------------------- drivers/scsi/iscsi_tcp.h | 5 -- 2 files changed, 54 insertions(+), 81 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index f2a08f7ed90..517bad160be 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 ed0b991d1e7..c9c8633c41a 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 */ -- GitLab From 2747fdb25726caa1a89229f43d99ca50af72576a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:08 -0500 Subject: [PATCH 1605/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 82 ++++++++++---------- drivers/infiniband/ulp/iser/iscsi_iser.h | 14 ++-- drivers/infiniband/ulp/iser/iser_initiator.c | 42 +++++----- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 7b146886906..baecca1ed42 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 bd5c1a554ea..96a600f127c 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 b82a5f2d4d3..4ea78fbeee9 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); } } -- GitLab From 9c19a7d0387124a508d2cdb38ebf8cd484631ad0 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:09 -0500 Subject: [PATCH 1606/2509] [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 --- drivers/scsi/libiscsi.c | 514 ++++++++++++++-------------- include/scsi/libiscsi.h | 22 +- include/scsi/scsi_transport_iscsi.h | 8 +- 3 files changed, 273 insertions(+), 271 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index ef92b1b0f16..92ee6d94aaf 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 d1c36759b35..176353c117b 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 3f24503dfdf..0553240796e 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); -- GitLab From 135a8ad4e09309d36dcb8b5c7f55db0b6a15b2d6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:10 -0500 Subject: [PATCH 1607/2509] [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 --- drivers/scsi/iscsi_tcp.c | 262 +++++++++++++++++++-------------------- drivers/scsi/iscsi_tcp.h | 2 +- 2 files changed, 132 insertions(+), 132 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 517bad160be..33cd0ca7cc8 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 c9c8633c41a..498d8ca3984 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 + -- GitLab From 2261ec3d686e35c1a6088ab7f00a1d02b528b994 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:11 -0500 Subject: [PATCH 1608/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 114 +++++------ drivers/infiniband/ulp/iser/iscsi_iser.h | 24 +-- drivers/infiniband/ulp/iser/iser_initiator.c | 190 +++++++++---------- drivers/infiniband/ulp/iser/iser_memory.c | 77 ++++---- 4 files changed, 203 insertions(+), 202 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index baecca1ed42..86d9c42f0d3 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 96a600f127c..05431f270fe 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 4ea78fbeee9..35af60a23c6 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 cac50c4dc15..48f2a601fc2 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); -- GitLab From 7970634b81a6e3561954517bca42615542c4535b Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:12 -0500 Subject: [PATCH 1609/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libiscsi.c | 4 +- drivers/scsi/scsi_transport_iscsi.c | 125 +++++++++++++++++------ include/scsi/libiscsi.h | 2 +- include/scsi/scsi_transport_iscsi.h | 6 +- 6 files changed, 104 insertions(+), 37 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 86d9c42f0d3..3a89039e9a9 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 33cd0ca7cc8..aa3c7f0c550 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 92ee6d94aaf..e88b726ab2e 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 6b8516a0970..ac9d298f54e 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 176353c117b..13c92d7ba96 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 0553240796e..d6b82319556 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; -- GitLab From d82ff9be733a2e6da4f6c2ab4e9216f3f536503d Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:13 -0500 Subject: [PATCH 1610/2509] [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 --- drivers/scsi/scsi_transport_iscsi.c | 190 +++++++++++++++++++++++----- include/scsi/iscsi_if.h | 2 +- include/scsi/scsi_transport_iscsi.h | 19 ++- 3 files changed, 172 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ac9d298f54e..c3c07ccccca 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 801a677777c..a0f13a280e7 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 d6b82319556..f5444e033cc 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 -- GitLab From 412eeafa0a51a8d86545d0be637bf84e4374fccf Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:14 -0500 Subject: [PATCH 1611/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 87 +++++++++++------------- drivers/infiniband/ulp/iser/iscsi_iser.h | 4 +- drivers/infiniband/ulp/iser/iser_verbs.c | 14 +--- 3 files changed, 43 insertions(+), 62 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 3a89039e9a9..42e95b83309 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 05431f270fe..cdf48763b08 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 5daed2bd710..81b45d4d9aa 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; } /** -- GitLab From 06520edea0fc7007985fa4cd51560149feb3f442 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:15 -0500 Subject: [PATCH 1612/2509] [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 --- drivers/scsi/iscsi_tcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index aa3c7f0c550..92d03195900 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; } -- GitLab From 88dfd340b9dece8fcaa1a2d4c782338926c017f7 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:16 -0500 Subject: [PATCH 1613/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 3 +- drivers/scsi/iscsi_tcp.c | 3 +- drivers/scsi/libiscsi.c | 20 ++++++ drivers/scsi/scsi_transport_iscsi.c | 6 +- include/scsi/iscsi_if.h | 79 +++++++++++++----------- include/scsi/libiscsi.h | 2 + 6 files changed, 74 insertions(+), 39 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 42e95b83309..08edbaf8922 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 92d03195900..7552dd8a88f 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 e88b726ab2e..c1af2aa8e4e 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 c3c07ccccca..9fd5c6d87ed 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 a0f13a280e7..16be12f1cbe 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 13c92d7ba96..21cfb1d5483 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; -- GitLab From 3cf7b233ffc45d4fc381221f74d24f10e692c4ea Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:17 -0500 Subject: [PATCH 1614/2509] [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 --- drivers/scsi/libiscsi.c | 49 ++++++++++++++++++++++++++++------------- include/scsi/libiscsi.h | 9 ++++---- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c1af2aa8e4e..c723e60f02b 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 21cfb1d5483..5bf0187e752 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) -- GitLab From 913e5bf435617aa529919a4f7567f849f9f35f9f Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:18 -0500 Subject: [PATCH 1615/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 20 +-- drivers/infiniband/ulp/iser/iscsi_iser.h | 2 - drivers/infiniband/ulp/iser/iser_initiator.c | 6 + drivers/scsi/iscsi_tcp.c | 73 ++++----- drivers/scsi/libiscsi.c | 152 +++++++++++-------- include/scsi/libiscsi.h | 8 +- 6 files changed, 144 insertions(+), 117 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 08edbaf8922..c02eabd383a 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 cdf48763b08..a547edeea96 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 35af60a23c6..c3608392213 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 7552dd8a88f..91cb1fd523f 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 c723e60f02b..9c267b44044 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 { @@ -696,6 +701,31 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, return 0; } +/** + * 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 @@ -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; @@ -2256,17 +2292,6 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, return; } - /* - * 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 @@ -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 5bf0187e752..5e75bb7f311 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -138,11 +138,6 @@ struct iscsi_conn { struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ 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 */ @@ -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 -- GitLab From 3a12b199fc820a52b8321c2b35172a1b3651120d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 21 May 2008 15:54:19 -0500 Subject: [PATCH 1616/2509] [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 --- drivers/scsi/iscsi_tcp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 91cb1fd523f..7c4ee39a1c4 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 -- GitLab From 8f333991ba8479fe8a9d72aea978db415e3c2f2a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 21 May 2008 15:54:20 -0500 Subject: [PATCH 1617/2509] [SCSI] scsi: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 9c267b44044..8b4e412a097 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; -- GitLab From 30e9ba9f2001f45960507f1963551311a67d0209 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 26 May 2008 11:31:19 +0300 Subject: [PATCH 1618/2509] [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 --- drivers/scsi/iscsi_tcp.c | 2 +- include/scsi/iscsi_proto.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 7c4ee39a1c4..0bd8b3dc3c1 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 e0593bfae62..f2a2c116948 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 */ -- GitLab From 3f27e3ed11e67c5ee19d560a50eafd93cf8c6682 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 29 May 2008 07:56:55 +0900 Subject: [PATCH 1619/2509] [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 --- block/bsg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index f0b7cd34321..7cdec32205d 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); -- GitLab From 597136ab70a6dccba5c40ee6eed88e881412429b Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 5 Jun 2008 00:12:59 -0400 Subject: [PATCH 1620/2509] [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 --- drivers/scsi/scsi_debug.c | 98 +++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index f6600bfb5bd..3901125455c 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 */ -- GitLab From 090507157f3bc43dd925fda50f8aca7d03b616b6 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 28 May 2008 15:32:55 -0400 Subject: [PATCH 1621/2509] [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 --- drivers/scsi/aacraid/commctrl.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 5fd83deab36..a7355260cfc 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", -- GitLab From 6362abd3e00d3161affad996fa53cc69a01fc6d1 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 5 Jun 2008 23:30:03 -0400 Subject: [PATCH 1622/2509] [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 --- drivers/scsi/scsi_lib.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 033c58a65f5..aa8d5de5883 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; -- GitLab From 24073b475d6d2bad8880434a16343ee1da816ea5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:54 +0200 Subject: [PATCH 1623/2509] [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 --- drivers/s390/scsi/Makefile | 2 +- drivers/s390/scsi/zfcp_aux.c | 518 ----------------------------------- drivers/s390/scsi/zfcp_dbf.c | 4 +- drivers/s390/scsi/zfcp_def.h | 8 +- drivers/s390/scsi/zfcp_erp.c | 188 +------------ drivers/s390/scsi/zfcp_ext.h | 12 +- drivers/s390/scsi/zfcp_fc.c | 305 +++++++++++++++++++++ drivers/s390/scsi/zfcp_fsf.c | 8 +- 8 files changed, 319 insertions(+), 726 deletions(-) create mode 100644 drivers/s390/scsi/zfcp_fc.c diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index d6a78f1a2f1..f775f9e6030 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 9a3c138ec50..9eb8827e19e 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 558dae9639f..01e817abe0a 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 fc61a8ed52d..d23c3b9b283 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 d05b3705489..ee19be13e70 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 e47ab8d05b6..91d58843205 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 00000000000..bb07c3bf225 --- /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 01f9b27daa8..8568b6f3f27 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); } } } -- GitLab From 45633fdc9615f9fd2a0ae18e301562298b15abf3 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:55 +0200 Subject: [PATCH 1624/2509] [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 --- drivers/s390/scsi/Makefile | 2 +- drivers/s390/scsi/zfcp_aux.c | 425 +++------------------------------- drivers/s390/scsi/zfcp_cfdc.c | 259 +++++++++++++++++++++ drivers/s390/scsi/zfcp_def.h | 43 ---- drivers/s390/scsi/zfcp_ext.h | 8 +- drivers/s390/scsi/zfcp_fsf.c | 246 ++------------------ drivers/s390/scsi/zfcp_fsf.h | 12 + 7 files changed, 331 insertions(+), 664 deletions(-) create mode 100644 drivers/s390/scsi/zfcp_cfdc.c diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index f775f9e6030..c0fa8ffe544 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 9eb8827e19e..735f7af43d6 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 00000000000..ec2abceca6d --- /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 d23c3b9b283..72f225817eb 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 91d58843205..867972898cb 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 8568b6f3f27..de42a01fc4b 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 8b1a7d9c840..598eba9baa3 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; -- GitLab From fa04c2816883a49ec518514f6c19767d54be20b5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:56 +0200 Subject: [PATCH 1625/2509] [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 --- drivers/s390/scsi/zfcp_ccw.c | 150 ++++++++++++----------------------- 1 file changed, 50 insertions(+), 100 deletions(-) diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 66d3b88844b..da472e865e5 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); +} -- GitLab From 00bab91066a49468bfa4f6d5c8ad5e9ec53b7ea3 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Tue, 10 Jun 2008 18:20:57 +0200 Subject: [PATCH 1626/2509] [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 --- drivers/s390/scsi/zfcp_aux.c | 45 +- drivers/s390/scsi/zfcp_dbf.c | 3 +- drivers/s390/scsi/zfcp_def.h | 26 +- drivers/s390/scsi/zfcp_erp.c | 114 +---- drivers/s390/scsi/zfcp_ext.h | 18 +- drivers/s390/scsi/zfcp_fsf.c | 178 +++----- drivers/s390/scsi/zfcp_qdio.c | 815 +++++++++++++--------------------- 7 files changed, 412 insertions(+), 787 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 735f7af43d6..7084a6ae109 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 01e817abe0a..c47c23a01c7 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 72f225817eb..5fcb555e148 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 ee19be13e70..4a6d08363d4 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -113,41 +113,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 * @@ -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 867972898cb..6ffe2068ba8 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 de42a01fc4b..cc48a6462e6 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 e71547357f6..bd6561d5358 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; +} -- GitLab From 553448f6c4838a1e4bed2bc9301c748278d7d9ce Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:58 +0200 Subject: [PATCH 1627/2509] [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 --- drivers/s390/scsi/Makefile | 2 +- drivers/s390/scsi/zfcp_aux.c | 75 +- drivers/s390/scsi/zfcp_dbf.c | 41 +- drivers/s390/scsi/zfcp_def.h | 124 +- drivers/s390/scsi/zfcp_erp.c | 293 +---- drivers/s390/scsi/zfcp_ext.h | 20 +- drivers/s390/scsi/zfcp_fsf.c | 1557 +++++------------------- drivers/s390/scsi/zfcp_fsf.h | 20 +- drivers/s390/scsi/zfcp_scsi.c | 64 +- drivers/s390/scsi/zfcp_sysfs_adapter.c | 23 +- drivers/s390/scsi/zfcp_sysfs_driver.c | 106 -- drivers/s390/scsi/zfcp_sysfs_port.c | 23 +- drivers/s390/scsi/zfcp_sysfs_unit.c | 23 +- 13 files changed, 396 insertions(+), 1975 deletions(-) delete mode 100644 drivers/s390/scsi/zfcp_sysfs_driver.c diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index c0fa8ffe544..1aa46500f65 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 7084a6ae109..47739f4f670 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 c47c23a01c7..7c72f502eb0 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 5fcb555e148..73425dbb2be 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 4a6d08363d4..c06156b288e 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 6ffe2068ba8..9aa412bd663 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 cc48a6462e6..01ed5fb46c4 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 598eba9baa3..6ce2f1e4b00 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 4b0c85acb0f..a96e5c3b946 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 ccbba4dd3a7..1f2a8c21b73 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 651edd58906..00000000000 --- 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 703c1b5cb60..438675f2978 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 80fb2c2cf48..587d9e3e12d 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 -- GitLab From 85a82392fe6fe7620d8fe0eb694f926cefe62e1f Mon Sep 17 00:00:00 2001 From: Sven Schuetz Date: Tue, 10 Jun 2008 18:20:59 +0200 Subject: [PATCH 1628/2509] [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 --- drivers/s390/scsi/zfcp_scsi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index a96e5c3b946..446fb1da25d 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, -- GitLab From cc8c282963bd258a5bf49d3aa52675a4ae6d31f6 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Tue, 10 Jun 2008 18:21:00 +0200 Subject: [PATCH 1629/2509] [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 --- drivers/s390/scsi/zfcp_aux.c | 36 ++-- drivers/s390/scsi/zfcp_dbf.c | 4 + drivers/s390/scsi/zfcp_def.h | 5 + drivers/s390/scsi/zfcp_erp.c | 42 +++-- drivers/s390/scsi/zfcp_ext.h | 4 +- drivers/s390/scsi/zfcp_fc.c | 248 +++++++++++++++++++++++++ drivers/s390/scsi/zfcp_fsf.c | 3 + drivers/s390/scsi/zfcp_sysfs_adapter.c | 25 +++ 8 files changed, 336 insertions(+), 31 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 47739f4f670..2bd80fdccef 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 7c72f502eb0..3e9f0abb22f 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 73425dbb2be..1e837d46ea7 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 c06156b288e..9b9c999cf39 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 9aa412bd663..c3b51338abf 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 bb07c3bf225..aa2d9a668d1 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 01ed5fb46c4..243e792f240 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 1f2a8c21b73..a4cae60f69d 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -84,6 +84,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 @@ -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, -- GitLab From 235f7f25f4928f5075dbebdfb9ca2c5d90db882c Mon Sep 17 00:00:00 2001 From: Martin Peschke Date: Tue, 10 Jun 2008 18:21:01 +0200 Subject: [PATCH 1630/2509] [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 --- drivers/s390/scsi/zfcp_sysfs_adapter.c | 46 -------------------------- 1 file changed, 46 deletions(-) diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index a4cae60f69d..3985f1f1c29 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -39,51 +39,6 @@ ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", 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 @@ -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, -- GitLab From 915caaaf622172bd3451e7b76ba9cfcea80e87c7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:38 -0400 Subject: [PATCH 1631/2509] [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 --- drivers/scsi/lpfc/lpfc_scsi.c | 201 ++++++++++++++-------------------- 1 file changed, 80 insertions(+), 121 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0910a9ab76a..3926affaf72 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; } -- GitLab From 0d2b6b83030d6a88cbf7db57f84f2daf0e0b251b Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:47 -0400 Subject: [PATCH 1632/2509] [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 --- drivers/scsi/lpfc/lpfc_els.c | 141 +++++++--------------------- drivers/scsi/lpfc/lpfc_hbadisc.c | 23 ++--- drivers/scsi/lpfc/lpfc_init.c | 3 + drivers/scsi/lpfc/lpfc_nportdisc.c | 145 +++++++++++------------------ 4 files changed, 99 insertions(+), 213 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 886c5f1b11d..d418c7c1251 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 7cb68feb04f..f3dc19dfac5 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 fa757b251f8..6fcddda5851 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 d08c4c89074..6688a8689b5 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; } -- GitLab From 5e9d9b8276980fc5dfa88ce34f6ec88ce3026232 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:53 -0400 Subject: [PATCH 1633/2509] [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 --- drivers/scsi/lpfc/lpfc.h | 20 +++++-- drivers/scsi/lpfc/lpfc_ct.c | 16 +++--- drivers/scsi/lpfc/lpfc_els.c | 33 +++++------- drivers/scsi/lpfc/lpfc_hbadisc.c | 93 ++++++++------------------------ drivers/scsi/lpfc/lpfc_init.c | 13 +++-- drivers/scsi/lpfc/lpfc_scsi.c | 26 ++++----- drivers/scsi/lpfc/lpfc_sli.c | 36 ++++++------- 7 files changed, 97 insertions(+), 140 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ec0b0f6e5e1..e3e5b540e36 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 153afae567b..5442ce33615 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 d418c7c1251..5d69dee85a8 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 f3dc19dfac5..ba4873c9e2c 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 6fcddda5851..53cedbafffb 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 3926affaf72..1e88b7a8a45 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 70a0a9eab21..3dba3a967ed 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); -- GitLab From 495a714c50e2c6ca6357129812f983b3ac0a32f2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:59 -0400 Subject: [PATCH 1634/2509] [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 --- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_attr.c | 3 +-- drivers/scsi/lpfc/lpfc_crtn.h | 3 ++- drivers/scsi/lpfc/lpfc_ct.c | 6 +++--- drivers/scsi/lpfc/lpfc_els.c | 7 ++----- drivers/scsi/lpfc/lpfc_hbadisc.c | 4 ++++ drivers/scsi/lpfc/lpfc_init.c | 18 ++++++++++++++---- drivers/scsi/lpfc/lpfc_scsi.c | 5 ++--- drivers/scsi/lpfc/lpfc_sli.c | 13 +++++++------ drivers/scsi/lpfc/lpfc_vport.c | 16 +++++++++++++++- 10 files changed, 51 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index e3e5b540e36..e0e018d1265 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 960baaf11fb..37bfa0bd1da 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 7c9f8317d97..1b8245213b8 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 5442ce33615..7fc74cf5823 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 5d69dee85a8..f54e0f7eaee 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 ba4873c9e2c..a98d11bf357 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 53cedbafffb..5b6e5395c8e 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 1e88b7a8a45..c94da4f2b8a 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 3dba3a967ed..f40aa7b905f 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 6feaf59b0b1..109f89d9883 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) -- GitLab From ff0f4cb5ea322dcc32d08bab2d758c050ba1ab07 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:53:02 -0400 Subject: [PATCH 1635/2509] [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 --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index b22b893019f..ad24cacfbe1 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" -- GitLab From c95fddc729fafb43f420747027eeb998c2e5e798 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:32 -0500 Subject: [PATCH 1636/2509] [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 --- drivers/scsi/scsi_transport_iscsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9fd5c6d87ed..bc0f74d4ea0 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, -- GitLab From 8e9a20cee4511be4560f9c858d9994eb6913731e Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:33 -0500 Subject: [PATCH 1637/2509] [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 --- drivers/infiniband/ulp/iser/iscsi_iser.c | 1 - drivers/scsi/iscsi_tcp.c | 1 - drivers/scsi/libiscsi.c | 6 ++++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index c02eabd383a..a56931e0397 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 0bd8b3dc3c1..2a2f0094570 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 8b4e412a097..299e075a7b3 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 -- GitLab From 4c2133c82385c31dd3eed76b07da1e986eb00294 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:34 -0500 Subject: [PATCH 1638/2509] [SCSI] iscsi class: update version number Update iscsi class version number. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index bc0f74d4ea0..8e34f3c0857 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; -- GitLab From f80f868ec463b0463b332cdb704fe5438f013f98 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:35 -0500 Subject: [PATCH 1639/2509] [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 --- drivers/scsi/scsi_transport_iscsi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 8e34f3c0857..3af7cbcc5c5 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); -- GitLab From eac6e8e449647cbb9efee53977c8bfee0aa7d69e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 19 Jun 2008 10:02:58 -0600 Subject: [PATCH 1640/2509] [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 --- drivers/scsi/scsi_debug.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3901125455c..01d11a01ffb 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, -- GitLab From a793804f25fb2c0fe2b784450092699ea3475332 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 30 Sep 2007 17:10:42 -0700 Subject: [PATCH 1641/2509] [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 --- drivers/scsi/esp_scsi.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index a0b6d414953..3d5ad243e77 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); -- GitLab From dbfe54a9c9a9e31cdf71704e4e70d10d22a57264 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Thu, 19 Jun 2008 20:20:12 -0700 Subject: [PATCH 1642/2509] [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 --- drivers/scsi/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 7886ec6e5f8..994943f3e13 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" -- GitLab From aa91696e56a0870db5754610e9f9b937e77507e0 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 17 Jun 2008 12:47:32 -0400 Subject: [PATCH 1643/2509] [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 --- drivers/scsi/sd.c | 2 +- {include => drivers}/scsi/sd.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {include => drivers}/scsi/sd.h (100%) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 01cefbb2d53..e19691f880b 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/include/scsi/sd.h b/drivers/scsi/sd.h similarity index 100% rename from include/scsi/sd.h rename to drivers/scsi/sd.h -- GitLab From 5b635da11e3a6387172abd651d26d8ef54b1fbc7 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 25 Jun 2008 11:22:41 -0400 Subject: [PATCH 1644/2509] [SCSI] sd: Move scsi_disk() accessor function to sd.h Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 5 ----- drivers/scsi/sd.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e19691f880b..71069d952dc 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 4f032d48cb6..03a3d45cfa4 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, \ -- GitLab From f11f594edba7f689af9792a5673ed59d660ad371 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 25 Jun 2008 11:22:42 -0400 Subject: [PATCH 1645/2509] [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 --- include/linux/crc-t10dif.h | 8 +++++ lib/Kconfig | 7 ++++ lib/Makefile | 1 + lib/crc-t10dif.c | 67 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 include/linux/crc-t10dif.h create mode 100644 lib/crc-t10dif.c diff --git a/include/linux/crc-t10dif.h b/include/linux/crc-t10dif.h new file mode 100644 index 00000000000..a9c96d865ee --- /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 8cc8e8722a3..c7ad7a5b353 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 74b0cfb1fcc..237a8298f8c 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 00000000000..fbbd66ed86c --- /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"); -- GitLab From 39120e11705782c77d3a47d7d2927676fd8e3aaa Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 1 Jul 2008 13:03:19 -0500 Subject: [PATCH 1646/2509] [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 --- drivers/scsi/sg.c | 3 +++ include/scsi/sg.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ea0edd1b2e7..2010fa039cf 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 519c49a0fc1..934ae389671 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() */ -- GitLab From 072b91f9c6510d0ec4a49d07dbc318760c7da7b3 Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 1 Jul 2008 13:14:30 -0500 Subject: [PATCH 1647/2509] [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 --- drivers/scsi/Kconfig | 19 + drivers/scsi/Makefile | 1 + drivers/scsi/ibmvscsi/Makefile | 1 + drivers/scsi/ibmvscsi/ibmvfc.c | 3910 ++++++++++++++++++++++++++++++++ drivers/scsi/ibmvscsi/ibmvfc.h | 682 ++++++ 5 files changed, 4613 insertions(+) create mode 100644 drivers/scsi/ibmvscsi/ibmvfc.c create mode 100644 drivers/scsi/ibmvscsi/ibmvfc.h diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 994943f3e13..26be540d1dd 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 aa8272e188e..a8149677de2 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 6ac0633d545..a423d963362 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 00000000000..eb702b96d57 --- /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 00000000000..057f3c01ed6 --- /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 -- GitLab From c57a39a45a76bc8ecdd2c8a9bc7cf7be3ed73fe1 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:31 +0200 Subject: [PATCH 1648/2509] [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 --- drivers/s390/scsi/zfcp_fc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index aa2d9a668d1..34c9b20ce49 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; -- GitLab From 3968ce800f45d8795ceb6f186c1efe420c98e1b0 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:32 +0200 Subject: [PATCH 1649/2509] [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 --- drivers/s390/scsi/zfcp_fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 34c9b20ce49..5d9367d9a12 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; -- GitLab From 7afe29f7dd6dccbe454d7fd6cd6a5a7f7bcbc530 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:33 +0200 Subject: [PATCH 1650/2509] [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 --- drivers/s390/scsi/zfcp_aux.c | 15 +++++++-------- drivers/s390/scsi/zfcp_def.h | 3 +-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 2bd80fdccef..bfcd1ba28ae 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 1e837d46ea7..202f7e66c44 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 */ -- GitLab From 5d4e226246331087799a01c267ec72e5931ff190 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:34 +0200 Subject: [PATCH 1651/2509] [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 --- drivers/s390/scsi/zfcp_def.h | 2 -- drivers/s390/scsi/zfcp_ext.h | 1 - drivers/s390/scsi/zfcp_qdio.c | 27 +++++++++++---------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 202f7e66c44..e8383b7331b 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 c3b51338abf..368b304d1e3 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 bd6561d5358..b8ed42bb5c9 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, @@ -365,22 +376,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) return 0; } -/** - * 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 -- GitLab From feac6a07c4a3578bffd6769bb4927e8a7e1f3ffe Mon Sep 17 00:00:00 2001 From: Martin Petermann Date: Wed, 2 Jul 2008 10:56:35 +0200 Subject: [PATCH 1652/2509] [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 --- drivers/s390/scsi/zfcp_ext.h | 2 -- drivers/s390/scsi/zfcp_fsf.c | 20 ++++++++++---------- drivers/s390/scsi/zfcp_scsi.c | 24 +----------------------- include/scsi/scsi.h | 17 +++++++++++++++++ 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 368b304d1e3..f95dc99339f 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 243e792f240..150e78dd00b 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 446fb1da25d..160307382d2 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 2b5b9356c31..00137a7769e 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); -- GitLab From f76af7d7e36373179be7a9e09f6b0aae330549b7 Mon Sep 17 00:00:00 2001 From: Martin Petermann Date: Wed, 2 Jul 2008 10:56:36 +0200 Subject: [PATCH 1653/2509] [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 --- drivers/s390/scsi/zfcp_dbf.c | 3 +- drivers/s390/scsi/zfcp_def.h | 6 - drivers/s390/scsi/zfcp_ext.h | 5 - drivers/s390/scsi/zfcp_fsf.c | 4 +- drivers/s390/scsi/zfcp_scsi.c | 555 +++++++++++----------------------- 5 files changed, 184 insertions(+), 389 deletions(-) diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 3e9f0abb22f..566627f3a69 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 e8383b7331b..7ac830c3909 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 f95dc99339f..892476c17ff 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 150e78dd00b..22e3aa61278 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 160307382d2..f8594a2e3f5 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, + }, +}; + -- GitLab From 317e6b6519b5a34263a33f150ed57ad468b26a64 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:37 +0200 Subject: [PATCH 1654/2509] [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 --- drivers/s390/scsi/zfcp_aux.c | 583 +++++++++++----------------- drivers/s390/scsi/zfcp_ccw.c | 4 +- drivers/s390/scsi/zfcp_def.h | 13 - drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 4 +- drivers/s390/scsi/zfcp_fc.c | 18 +- drivers/s390/scsi/zfcp_sysfs_port.c | 2 +- 7 files changed, 238 insertions(+), 388 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index bfcd1ba28ae..7777729419e 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 da472e865e5..391dd29749f 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 7ac830c3909..d69d280359d 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 9b9c999cf39..4d797e5264d 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 892476c17ff..9caa081e52e 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 5d9367d9a12..fbe2c76df4d 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 438675f2978..e183ff8bdb2 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; -- GitLab From 60221920706a01bef89af2577f9a90a8eeb4e662 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:38 +0200 Subject: [PATCH 1655/2509] [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 --- drivers/s390/scsi/Makefile | 3 +- drivers/s390/scsi/zfcp_aux.c | 42 ++- drivers/s390/scsi/zfcp_def.h | 9 - drivers/s390/scsi/zfcp_ext.h | 16 +- drivers/s390/scsi/zfcp_scsi.c | 206 +--------- drivers/s390/scsi/zfcp_sysfs.c | 496 +++++++++++++++++++++++++ drivers/s390/scsi/zfcp_sysfs_adapter.c | 232 ------------ drivers/s390/scsi/zfcp_sysfs_port.c | 278 -------------- drivers/s390/scsi/zfcp_sysfs_unit.c | 150 -------- 9 files changed, 539 insertions(+), 893 deletions(-) create mode 100644 drivers/s390/scsi/zfcp_sysfs.c delete mode 100644 drivers/s390/scsi/zfcp_sysfs_adapter.c delete mode 100644 drivers/s390/scsi/zfcp_sysfs_port.c delete mode 100644 drivers/s390/scsi/zfcp_sysfs_unit.c diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index 1aa46500f65..cb301cc6178 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 7777729419e..5b9ca3cde89 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 d69d280359d..2af043a5c74 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 9caa081e52e..f0d6947ae07 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 f8594a2e3f5..e6d8ea8051a 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 00000000000..2e85c6c49e7 --- /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 3985f1f1c29..00000000000 --- 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 e183ff8bdb2..00000000000 --- 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 587d9e3e12d..00000000000 --- 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); -} -- GitLab From c41f8cbddd4e0e72951e0575165dea8ea26f1c4b Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:39 +0200 Subject: [PATCH 1656/2509] [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 --- drivers/s390/scsi/zfcp_aux.c | 4 +- drivers/s390/scsi/zfcp_dbf.c | 2 +- drivers/s390/scsi/zfcp_def.h | 31 +- drivers/s390/scsi/zfcp_ext.h | 12 +- drivers/s390/scsi/zfcp_fc.c | 11 +- drivers/s390/scsi/zfcp_fsf.c | 4135 ++++++++++++--------------------- drivers/s390/scsi/zfcp_fsf.h | 31 +- drivers/s390/scsi/zfcp_qdio.c | 6 +- drivers/s390/scsi/zfcp_scsi.c | 5 +- 9 files changed, 1585 insertions(+), 2652 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 5b9ca3cde89..90abfd06ed5 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 566627f3a69..36169c6944f 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 2af043a5c74..206b6e7a8bf 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 f0d6947ae07..2845693413f 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 fbe2c76df4d..e984469bb98 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 22e3aa61278..e6d815593b4 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 6ce2f1e4b00..bf94b4da076 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 b8ed42bb5c9..72e3094796d 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 e6d8ea8051a..aeae56b00b4 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; -- GitLab From 287ac01acf22ab6aaaf9f5a4919ce2449c8b391c Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:40 +0200 Subject: [PATCH 1657/2509] [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 --- drivers/s390/scsi/zfcp_def.h | 45 - drivers/s390/scsi/zfcp_erp.c | 3500 +++++++++++++--------------------- drivers/s390/scsi/zfcp_ext.h | 25 +- drivers/s390/scsi/zfcp_fsf.c | 43 +- 4 files changed, 1345 insertions(+), 2268 deletions(-) diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 206b6e7a8bf..67f45fc62f5 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 4d797e5264d..643ac4bba5b 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 2845693413f..13eb0a67da6 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 e6d815593b4..19c1ca91387 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); -- GitLab From 92c299d11acd3f3e75a721acb8f57c457d5c394f Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:41 +0200 Subject: [PATCH 1658/2509] [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 --- drivers/s390/scsi/zfcp_ext.h | 244 +++++++++++++++++------------------ 1 file changed, 119 insertions(+), 125 deletions(-) diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 13eb0a67da6..8065b2b224b 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 */ -- GitLab From 2476b4d0426e1d6d4a42b2f7ae08f668b2cfe510 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 3 Jul 2008 11:31:55 -0500 Subject: [PATCH 1659/2509] [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 --- drivers/scsi/scsi_lib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index aa8d5de5883..0451903452e 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; } } -- GitLab From 453cd0f3ff3bf25d86c96e62d271ba238f06d5ff Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 3 Jul 2008 23:47:33 -0700 Subject: [PATCH 1660/2509] [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 --- drivers/scsi/hosts.c | 2 +- drivers/scsi/scsi_scan.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 3690360d7a7..497ca68d1ff 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 a00eee6f7be..196fe3af0d5 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, }; -- GitLab From 02a1e3ce7df624ba91e8ff06e172f448746ad76a Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 6 Jul 2008 17:01:34 +0400 Subject: [PATCH 1661/2509] [SCSI] scsi_cmnd.h: remove double inclusion of linux/blkdev.h Signed-off-by: Alexander Beregalov Signed-off-by: James Bottomley --- include/scsi/scsi_cmnd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 3e46dfae819..66c944849d6 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; -- GitLab From d7f305e9a08040649b0800245e67708df58cdb55 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2008 10:50:25 +1000 Subject: [PATCH 1662/2509] [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 --- drivers/scsi/sym53c8xx_2/sym_misc.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h index 0433d5d0caf..430537183c1 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) -- GitLab From 8df5fc042c8e7c08dc438c8198b62407ee1e91a0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 7 Jul 2008 15:50:01 -0500 Subject: [PATCH 1663/2509] [SCSI] bsg: fix oops on remove If you do a modremove of any sas driver, you run into an oops on shutdown when the host is removed (coming from the host bsg device). The root cause seems to be that there's a use after free of the bsg_class_device: In bsg_kref_release_function, this is used (to do a put_device(bcg->parent) after bcg->release has been called. In sas (and possibly many other things) bcd->release frees the queue which contains the bsg_class_device, so we get a put_device on unreferenced memory. Fix this by taking a copy of the pointer to the parent before releasing bsg. Acked-by: FUJITA Tomonori Signed-off-by: James Bottomley --- block/bsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/bsg.c b/block/bsg.c index f0b7cd34321..54d617f7df3 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -709,11 +709,12 @@ static void bsg_kref_release_function(struct kref *kref) { struct bsg_class_device *bcd = container_of(kref, struct bsg_class_device, ref); + struct device *parent = bcd->parent; if (bcd->release) bcd->release(bcd->parent); - put_device(bcd->parent); + put_device(parent); } static int bsg_put_device(struct bsg_device *bd) -- GitLab From 6eb9d32298290b956693fd85c815b817d39a9505 Mon Sep 17 00:00:00 2001 From: Andre Schwarz Date: Thu, 10 Jul 2008 11:53:16 +0200 Subject: [PATCH 1664/2509] 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 --- arch/powerpc/platforms/52xx/mpc52xx_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index e3428ddd904..5a382bb15f6 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 -- GitLab From 0d1cde235874b00905bce23f659690d060ebf475 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 30 Jun 2008 19:01:26 -0400 Subject: [PATCH 1665/2509] 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 --- arch/powerpc/sysdev/fsl_soc.c | 133 ---------------------------------- drivers/i2c/busses/i2c-mpc.c | 104 +++++++++++++++----------- 2 files changed, 60 insertions(+), 177 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ca54563d5c7..ebcec7362f9 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 a076129de7e..4fdfb62d6f3 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); -- GitLab From f40987b64d0f4d40b006ce09e37161b57c1e970b Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 8 Jul 2008 06:38:24 -0400 Subject: [PATCH 1666/2509] 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 --- drivers/of/of_i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index b2ccdcbeb89..5c015d310d4 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 { -- GitLab From b0852cb8841f35b124f4344d92abd8c0a6b54fcf Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 2 Jul 2008 11:56:40 +0200 Subject: [PATCH 1667/2509] 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 --- arch/powerpc/boot/dts/tqm5200.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts index 773a68e0005..3008bf8830c 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>; -- GitLab From e6a9192d066b30353b78ce1647070c0c171dd9a7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:16:27 +1000 Subject: [PATCH 1668/2509] powerpc/pata_mpc52xx: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely --- drivers/ata/pata_mpc52xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index bc79df6e7cb..a9e827356d0 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 -- GitLab From 76ef7dd030823518506d65237a12666fc3f5a0d4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:35:47 +1000 Subject: [PATCH 1669/2509] powerpc/mpc52xx_psc_spi: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely --- drivers/spi/mpc52xx_psc_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 681d62325d3..604e5f0a2d9 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 -- GitLab From 75195dabce797f49b7d96d272e4e9330873e4340 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:42:56 +1000 Subject: [PATCH 1670/2509] powerpc/mpc5200_wdt: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely --- drivers/watchdog/mpc5200_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 80a91d4cea1..77c1c2ae2cc 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include -- GitLab From 7ba6d6dc8d58c49cff0533819195b44fb35d6ece Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 1 Jul 2008 21:38:16 -0600 Subject: [PATCH 1671/2509] 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 --- arch/powerpc/sysdev/bestcomm/gen_bd.c | 95 +++++++++++++++++++++++++++ arch/powerpc/sysdev/bestcomm/gen_bd.h | 5 ++ 2 files changed, 100 insertions(+) diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c index 8d33eafbb3f..a3a134c35b0 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 5b6fa803c6a..de47260e69d 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__ */ -- GitLab From 08b6c06de5d3f37295f6dbf7010fb45ae5ee14a7 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 11 Jul 2008 16:17:58 -0600 Subject: [PATCH 1672/2509] 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 --- arch/powerpc/sysdev/bestcomm/bestcomm.c | 2 +- arch/powerpc/sysdev/bestcomm/sram.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 64ec7d62936..446c9ea85b3 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 99784383a84..5d74ef7a651 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; } -- GitLab From 4df64c3e58d28ffc5c61bdbdd733c5d0303b9f3c Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:01 -0600 Subject: [PATCH 1673/2509] 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 --- arch/powerpc/boot/dts/mpc5121ads.dts | 310 ++++++++++++++++++++++++++- 1 file changed, 299 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts index 94ad7b2b241..1f9036c317b 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"; }; }; -- GitLab From 137e95906e294913fab02162e8a1948ade49acb5 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:02 -0600 Subject: [PATCH 1674/2509] 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 --- Makefile | 1 + arch/powerpc/platforms/512x/Kconfig | 1 + arch/powerpc/platforms/512x/Makefile | 1 + arch/powerpc/platforms/512x/clock.c | 729 +++++++++++++++++++++++++++ 4 files changed, 732 insertions(+) create mode 100644 arch/powerpc/platforms/512x/clock.c diff --git a/Makefile b/Makefile index 6aff5f47c21..fc3ae9fc847 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 4c0da0c079e..162af067d12 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 232c89f2039..90910c1f725 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 00000000000..f416014ee72 --- /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); -- GitLab From fb1803224ea145e3424d6295d4aaa8e9fef70642 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:03 -0600 Subject: [PATCH 1675/2509] 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 --- arch/powerpc/platforms/512x/Kconfig | 15 +++- arch/powerpc/platforms/512x/Makefile | 3 +- arch/powerpc/platforms/512x/mpc5121_ads.c | 64 ++------------ arch/powerpc/platforms/512x/mpc5121_generic.c | 58 +++++++++++++ arch/powerpc/platforms/512x/mpc512x.h | 17 ++++ arch/powerpc/platforms/512x/mpc512x_shared.c | 83 +++++++++++++++++++ 6 files changed, 177 insertions(+), 63 deletions(-) create mode 100644 arch/powerpc/platforms/512x/mpc5121_generic.c create mode 100644 arch/powerpc/platforms/512x/mpc512x.h create mode 100644 arch/powerpc/platforms/512x/mpc512x_shared.c diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 162af067d12..5d72dc3435a 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 90910c1f725..8090e222a2d 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 50bd3a31902..3ec9ca34d8e 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 00000000000..2479de9e2d1 --- /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 00000000000..9c03693cb00 --- /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 00000000000..d8cd579f319 --- /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"); +} + -- GitLab From 1879f711d8c3960e0fd927f38ff885017a77291b Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:04 -0600 Subject: [PATCH 1676/2509] 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 --- arch/powerpc/platforms/512x/Kconfig | 1 + arch/powerpc/platforms/512x/Makefile | 2 +- arch/powerpc/platforms/512x/mpc5121_ads.c | 11 + arch/powerpc/platforms/512x/mpc5121_ads.h | 16 ++ .../powerpc/platforms/512x/mpc5121_ads_cpld.c | 204 ++++++++++++++++++ 5 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/512x/mpc5121_ads.h create mode 100644 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 5d72dc3435a..c62f893ede1 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 8090e222a2d..90be2f5717e 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 3ec9ca34d8e..5ebf6939a69 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 00000000000..662076cfee2 --- /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 00000000000..a6ce8056662 --- /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); +} -- GitLab From 77a76369475801ab8cbb338b9d8cfa92a491badb Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 12 Jul 2008 12:11:43 -0600 Subject: [PATCH 1677/2509] 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 --- MAINTAINERS | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8f0ec46a709..c984014a5ce 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 -- GitLab From 43f77e91eadbc290eb76a08110a039c809dde6c9 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Sat, 12 Jul 2008 13:47:49 -0700 Subject: [PATCH 1678/2509] drivers/char/pcmcia/ipwireless/hardware.c fix resource leak Coverity CID: 2172 RESOURCE_LEAK When pool_allocate() tries to enlarge a packet, if it can not allocate enough memory, it returns NULL without first freeing the old packet. This patch just frees the packet first. Signed-off-by: Darren Jenkins Acked-by: Jiri Kosina Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/pcmcia/ipwireless/hardware.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index ba6340ae98a..929101ecbae 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c @@ -590,8 +590,10 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, packet = kmalloc(sizeof(struct ipw_rx_packet) + old_packet->length + minimum_free_space, GFP_ATOMIC); - if (!packet) + if (!packet) { + kfree(old_packet); return NULL; + } memcpy(packet, old_packet, sizeof(struct ipw_rx_packet) + old_packet->length); -- GitLab From 4fc89e3911aa5357b55b85b60c4beaeb8a48a290 Mon Sep 17 00:00:00 2001 From: Darren Jenkins Date: Sat, 12 Jul 2008 13:47:50 -0700 Subject: [PATCH 1679/2509] drivers/isdn/i4l/isdn_common.c fix small resource leak Coverity CID: 1356 RESOURCE_LEAK I found a very old patch for this that was Acked but did not get applied https://lists.linux-foundation.org/pipermail/kernel-janitors/2006-September/016362.html There looks to be a small leak in isdn_writebuf_stub() in isdn_common.c, when copy_from_user() returns an un-copied data length (length != 0). The below patch should be a minimally invasive fix. Signed-off-by: Darren Jenkins Acked-by: Karsten Keil Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/i4l/isdn_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 0f3c66de69b..8d8c6b73616 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1977,8 +1977,10 @@ isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len) if (!skb) return -ENOMEM; skb_reserve(skb, hl); - if (copy_from_user(skb_put(skb, len), buf, len)) + if (copy_from_user(skb_put(skb, len), buf, len)) { + dev_kfree_skb(skb); return -EFAULT; + } ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); if (ret <= 0) dev_kfree_skb(skb); -- GitLab From f31ad92f34913043cf008d6e479e92dfbaf02df1 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sat, 12 Jul 2008 13:47:51 -0700 Subject: [PATCH 1680/2509] fbdev: bugfix for multiprocess defio This patch is a bugfix for how defio handles multiple processes manipulating the same framebuffer. Thanks to Bernard Blackham for identifying this bug. It occurs when two applications mmap the same framebuffer and concurrently write to the same page. Normally, this doesn't occur since only a single process mmaps the framebuffer. The symptom of the bug is that the mapping applications will hang. The cause is that defio incorrectly tries to add the same page twice to the pagelist. The solution I have is to walk the pagelist and check for a duplicate before adding. Since I needed to walk the pagelist, I now also keep the pagelist in sorted order. Signed-off-by: Jaya Kumar Cc: Bernard Blackham Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fb_defio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 24843fdd539..59df132cc37 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -74,6 +74,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, { struct fb_info *info = vma->vm_private_data; struct fb_deferred_io *fbdefio = info->fbdefio; + struct page *cur; /* this is a callback we get when userspace first tries to write to the page. we schedule a workqueue. that workqueue @@ -83,7 +84,24 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, /* protect against the workqueue changing the page list */ mutex_lock(&fbdefio->lock); - list_add(&page->lru, &fbdefio->pagelist); + + /* we loop through the pagelist before adding in order + to keep the pagelist sorted */ + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + /* this check is to catch the case where a new + process could start writing to the same page + through a new pte. this new access can cause the + mkwrite even when the original ps's pte is marked + writable */ + if (unlikely(cur == page)) + goto page_already_added; + else if (cur->index > page->index) + break; + } + + list_add_tail(&page->lru, &cur->lru); + +page_already_added: mutex_unlock(&fbdefio->lock); /* come back after delay to process the deferred IO */ -- GitLab From 05d81d2222beec7b63ac8c1c8cdb5bb4f82c2bad Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 12 Jul 2008 13:47:53 -0700 Subject: [PATCH 1681/2509] serial8250: sanity check nr_uarts on all paths. I had 8250.nr_uarts=16 in the boot line of a test kernel and I had a weird mysterious crash in sysfs. After taking an in-depth look I realized that CONFIG_SERIAL_8250_NR_UARTS was set to 4 and I was walking off the end of the serial8250_ports array. Ouch!!! Don't let this happen to someone else. Signed-off-by: Eric W. Biederman Acked-by: Alan Cox Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 1bc00b721e9..be95e55b228 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2623,6 +2623,9 @@ static struct console serial8250_console = { static int __init serial8250_console_init(void) { + if (nr_uarts > UART_NR) + nr_uarts = UART_NR; + serial8250_isa_init_ports(); register_console(&serial8250_console); return 0; -- GitLab From bca5c2c550f16d2dc2d21ffb7b4712bd0a7d32a9 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sat, 12 Jul 2008 13:47:54 -0700 Subject: [PATCH 1682/2509] ov7670: clean up ov7670_read semantics Cortland Setlow pointed out a bug in ov7670.c where the result from ov7670_read() was just being checked for !0, rather than <0. This made me realize that ov7670_read's semantics were rather confusing; it both fills in 'value' with the result, and returns it. This is goes against general kernel convention; so rather than fixing callers, let's fix the function. This makes ov7670_read return <0 in the case of an error, and 0 upon success. Thus, code like: res = ov7670_read(...); if (!res) goto error; ..will work properly. Signed-off-by: Cortland Setlow Signed-off-by: Andres Salomon Acked-by: Jonathan Corbet Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/ov7670.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 2bc6bdc9c1f..d7bfd30f74a 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -406,8 +406,10 @@ static int ov7670_read(struct i2c_client *c, unsigned char reg, int ret; ret = i2c_smbus_read_byte_data(c, reg); - if (ret >= 0) + if (ret >= 0) { *value = (unsigned char) ret; + ret = 0; + } return ret; } -- GitLab From 876550aa3e5f6448a1abae3704cbebcc50545998 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Sat, 12 Jul 2008 13:47:55 -0700 Subject: [PATCH 1683/2509] rtc-fm3130: fix chip naming Fix chip naming from fm3031-rtc to fm3031 Signed-off-by: Alessandro Zummo Cc: Sergey Lapin Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-fm3130.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 11644c8fca8..abfdfcbaa05 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -55,7 +55,7 @@ struct fm3130 { int alarm; }; static const struct i2c_device_id fm3130_id[] = { - { "fm3130-rtc", 0 }, + { "fm3130", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, fm3130_id); -- GitLab From 8ea9212cbd65db749543ec619e32fdff9a8b3408 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Sat, 12 Jul 2008 13:47:56 -0700 Subject: [PATCH 1684/2509] rtc-pcf8563: add chip id Add the rtc8564 chip entry Signed-off-by: Jon Smirl Signed-off-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pcf8563.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 0fc4c363078..748a502a635 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -302,6 +302,7 @@ static int pcf8563_remove(struct i2c_client *client) static const struct i2c_device_id pcf8563_id[] = { { "pcf8563", 0 }, + { "rtc8564", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, pcf8563_id); -- GitLab From d1a5d1979702cc57b9b80f636426ec7ad1655cad Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Sat, 12 Jul 2008 13:47:57 -0700 Subject: [PATCH 1685/2509] OProfile kernel maintainership changes Cc: Philippe Elie Cc: John Levon Cc: Maynard Johnson Cc: Richard Purdie Cc: Daniel Hansel Cc: Jason Yeh Cc: Andrew Morton Signed-off-by: Robert Richter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6476125363e..56a2f678019 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3082,8 +3082,8 @@ L: linux-scsi@vger.kernel.org S: Maintained OPROFILE -P: Philippe Elie -M: phil.el@wanadoo.fr +P: Robert Richter +M: robert.richter@amd.com L: oprofile-list@lists.sf.net S: Maintained -- GitLab From d3297a644a0ab784e0c810ceca6bf35a67868ad9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 12 Jul 2008 13:47:58 -0700 Subject: [PATCH 1686/2509] frv: fix irqs_disabled() to return an int, not an unsigned long Fix FRV irqs_disabled() to return an int, not an unsigned long to avoid this warning: kernel/sched.c: In function '__might_sleep': kernel/sched.c:8198: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-frv/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index d3a12a9079f..7742ec000cc 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h @@ -87,7 +87,7 @@ do { \ } while(0) #define irqs_disabled() \ - ({unsigned long flags; local_save_flags(flags); flags; }) + ({unsigned long flags; local_save_flags(flags); !!flags; }) #define local_irq_save(flags) \ do { \ -- GitLab From e911d0cc877ff027d5bd09fc33148ab76f0fdf0e Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sat, 12 Jul 2008 13:47:59 -0700 Subject: [PATCH 1687/2509] cifs: fix inode leak in cifs_get_inode_info_unix Try this: mount a share with unix extensions create a file on it umount the share You'll get the following message in the ring buffer: VFS: Busy inodes after unmount of cifs. Self-destruct in 5 seconds. Have a nice day... ...the problem is that cifs_get_inode_info_unix is creating and hashing a new inode even when it's going to return error anyway. The first lookup when creating a file returns an error so we end up leaking this inode before we do the actual create. This appears to be a regression caused by commit 0e4bbde94fdc33f5b3d793166b21bf768ca3e098. The following patch seems to fix it for me, and fixes a minor formatting nit as well. Signed-off-by: Jeff Layton Acked-by: Steven French Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/cifs/inode.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 722be543cee..2e904bd111c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -219,15 +219,15 @@ int cifs_get_inode_info_unix(struct inode **pinode, rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc) { - if (rc == -EREMOTE && !is_dfs_referral) { - is_dfs_referral = true; - cFYI(DBG2, ("DFS ref")); - /* for DFS, server does not give us real inode data */ - fill_fake_finddataunix(&find_data, sb); - rc = 0; - } - } + if (rc == -EREMOTE && !is_dfs_referral) { + is_dfs_referral = true; + cFYI(DBG2, ("DFS ref")); + /* for DFS, server does not give us real inode data */ + fill_fake_finddataunix(&find_data, sb); + rc = 0; + } else if (rc) + goto cgiiu_exit; + num_of_bytes = le64_to_cpu(find_data.NumOfBytes); end_of_file = le64_to_cpu(find_data.EndOfFile); @@ -236,7 +236,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, *pinode = new_inode(sb); if (*pinode == NULL) { rc = -ENOMEM; - goto cgiiu_exit; + goto cgiiu_exit; } /* Is an i_ino of zero legal? */ /* note ino incremented to unique num in new_inode */ -- GitLab From 536abdb0802f3fac1b217530741853843d63c281 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sat, 12 Jul 2008 13:48:00 -0700 Subject: [PATCH 1688/2509] cifs: fix wksidarr declaration to be big-endian friendly The current definition of wksidarr works fine on little endian arches (since cpu_to_le32 is a no-op there), but on big-endian arches, it fails to compile with this error: error: braced-group within expression allowed only inside a function The problem is that this static declaration has cpu_to_le32 embedded within it, and that expands into a function macro. We need to use __constant_cpu_to_le32() instead. Signed-off-by: Jeff Layton Cc: Steven French Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/cifs/cifsacl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 34902cff540..0e9fc2ba90e 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -34,11 +34,11 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, - {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"}, - {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} } + {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"}, + {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, + {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"}, + {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"}, + {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} } ; -- GitLab From 7ab073b6e0cde1544f4e79fadb75532528af7595 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 14:30:35 -0700 Subject: [PATCH 1689/2509] 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 --- arch/x86/kernel/pci-gart_64.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d0d18db5d2a..a614ee10f84 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: [PATCH 1690/2509] 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 --- arch/x86/kernel/cpu/amd_64.c | 1 + arch/x86/mm/pageattr.c | 4 ++-- arch/x86/mm/pat.c | 4 ++-- arch/x86/pci/i386.c | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c index bd182b7616e..7c36fb8a28d 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 0389cb8f6b1..fb6f2ab40dd 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 749766c3c5c..d4585077977 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 5281e343dd9..2aafb67dc5f 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; -- GitLab From 9958e810f8ac92f8a447035ee6555420ba27b847 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 14:32:45 -0700 Subject: [PATCH 1691/2509] 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 --- arch/x86/mm/init_64.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 122bcef222f..a25cc6fa220 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, -- GitLab From 7b479becdb8c1fb4ff6fbb2a4076c471c737b54c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 22:57:07 -0700 Subject: [PATCH 1692/2509] 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 --- arch/x86/kernel/e820.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index a5383ae2cbe..28c29180b38 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1048,11 +1048,6 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) # define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT #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 */ @@ -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); -- GitLab From 3d88cca7085cffce077f808f36551e9050eb9e3a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 22:52:55 -0700 Subject: [PATCH 1693/2509] 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 --- arch/x86/kernel/cpu/intel.c | 4 ++++ arch/x86/kernel/numaq_32.c | 7 ++++--- arch/x86/kernel/setup.c | 8 ++++++++ include/asm-x86/numaq.h | 2 ++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index fe9224c51d3..70609efdf1d 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 f0f1de1c4a1..5b20a5e7ac2 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 987b6fde3a9..36c540d4ac4 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 ef068d2465d..34b92d581fa 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) { -- GitLab From 3e84050c81ffb4961ef43d20e1fb1d7607167d83 Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Sun, 13 Jul 2008 02:10:29 +0200 Subject: [PATCH 1694/2509] 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 --- kernel/cpuset.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 9fceb97e989..798b3ab054e 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 -- GitLab From ce8b06b985ae48f9425de6e4641e77cb3613ef00 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sun, 13 Jul 2008 03:29:42 +0100 Subject: [PATCH 1695/2509] 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 --- arch/x86/kernel/acpi/boot.c | 1 - arch/x86/kernel/io_apic_32.c | 10 ---------- arch/x86/kernel/io_apic_64.c | 10 ---------- include/asm-x86/genapic_32.h | 5 ----- include/asm-x86/genapic_64.h | 6 ------ 5 files changed, 32 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 785700a08e9..f489d7a9be9 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 c50adb84ea6..603261a5885 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 9e645cba11c..b16ef029cf8 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 33a73f5ed22..b02ea6e17de 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 647e4e5c258..0f8504627c4 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 -- GitLab From 815224293e5aa4c7dc1638807889e345f385b38d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Jul 2008 21:48:54 -0500 Subject: [PATCH 1696/2509] 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 --- drivers/ide/legacy/ide-cs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index aa2ea3deac8..8b8b20d8691 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 -- GitLab From 090657e423f45a77151943f50165ae9565bfbf33 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Sun, 13 Jul 2008 20:12:11 +0800 Subject: [PATCH 1697/2509] 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 --- drivers/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index eb2ec2e0a14..e522144cba3 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. -- GitLab From 11369f356b66d363a615fde2c5526962f7683674 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Tue, 8 Jul 2008 14:35:21 -0700 Subject: [PATCH 1698/2509] 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 --- arch/x86/kernel/setup_percpu.c | 8 ++++---- include/asm-generic/topology.h | 3 ++- include/asm-x86/topology.h | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 5fc310f746f..cac68430d31 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 a6aea79bca4..54bbf6e04ee 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 98e5f17ea85..90ac7718469 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) -- GitLab From 0302c01b4b793cfbc5c7bf8723f6d14bf9bd7cf4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sun, 13 Jul 2008 12:13:59 -0700 Subject: [PATCH 1699/2509] 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 --- Documentation/HOWTO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 0291ade44c1..619e8caf30d 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 -- GitLab From 17d213f806dad629e9af36fc45f082b87ed7bceb Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sun, 13 Jul 2008 12:14:02 -0700 Subject: [PATCH 1700/2509] 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 --- security/device_cgroup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index fd764a0858d..1e2e28afba4 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, -- GitLab From ec229e830060091b9be63c8f873c1b2407a82821 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sun, 13 Jul 2008 12:14:04 -0700 Subject: [PATCH 1701/2509] 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 --- security/device_cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 1e2e28afba4..ddd92cec78e 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; } -- GitLab From 199a952876adbfc2b6c13b8b07adabebf4ff54b2 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 26 Jun 2008 10:06:43 +0800 Subject: [PATCH 1702/2509] 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 --- kernel/rcuclassic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index 214e1cde981..529190c485f 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) -- GitLab From bce7f793daec3e65ec5c5705d2457b81fe7b5725 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 13 Jul 2008 14:51:29 -0700 Subject: [PATCH 1703/2509] Linux 2.6.26 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6315424a00b..e3c5eb66ec5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -EXTRAVERSION = -rc9 +EXTRAVERSION = NAME = Rotary Wombat # *DOCUMENTATION* -- GitLab From c0e09200dc0813972442e550a5905a132768e56c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 10:09:59 +1000 Subject: [PATCH 1704/2509] 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 --- drivers/Makefile | 1 + drivers/char/Makefile | 1 - drivers/char/drm/Makefile | 40 ------------------- drivers/gpu/Makefile | 1 + drivers/{char => gpu}/drm/Kconfig | 0 drivers/gpu/drm/Makefile | 26 ++++++++++++ drivers/{char => gpu}/drm/README.drm | 0 drivers/{char => gpu}/drm/ati_pcigart.c | 0 drivers/{char => gpu}/drm/drm_agpsupport.c | 0 drivers/{char => gpu}/drm/drm_auth.c | 0 drivers/{char => gpu}/drm/drm_bufs.c | 0 drivers/{char => gpu}/drm/drm_context.c | 0 drivers/{char => gpu}/drm/drm_dma.c | 0 drivers/{char => gpu}/drm/drm_drawable.c | 0 drivers/{char => gpu}/drm/drm_drv.c | 0 drivers/{char => gpu}/drm/drm_fops.c | 0 drivers/{char => gpu}/drm/drm_hashtab.c | 0 drivers/{char => gpu}/drm/drm_ioc32.c | 0 drivers/{char => gpu}/drm/drm_ioctl.c | 0 drivers/{char => gpu}/drm/drm_irq.c | 0 drivers/{char => gpu}/drm/drm_lock.c | 0 drivers/{char => gpu}/drm/drm_memory.c | 0 drivers/{char => gpu}/drm/drm_mm.c | 0 drivers/{char => gpu}/drm/drm_pci.c | 0 drivers/{char => gpu}/drm/drm_proc.c | 0 drivers/{char => gpu}/drm/drm_scatter.c | 0 drivers/{char => gpu}/drm/drm_sman.c | 0 drivers/{char => gpu}/drm/drm_stub.c | 0 drivers/{char => gpu}/drm/drm_sysfs.c | 0 drivers/{char => gpu}/drm/drm_vm.c | 0 drivers/gpu/drm/i810/Makefile | 8 ++++ drivers/{char/drm => gpu/drm/i810}/i810_dma.c | 0 drivers/{char/drm => gpu/drm/i810}/i810_drv.c | 0 drivers/{char/drm => gpu/drm/i810}/i810_drv.h | 0 drivers/gpu/drm/i830/Makefile | 8 ++++ drivers/{char/drm => gpu/drm/i830}/i830_dma.c | 0 drivers/{char/drm => gpu/drm/i830}/i830_drv.c | 0 drivers/{char/drm => gpu/drm/i830}/i830_drv.h | 0 drivers/{char/drm => gpu/drm/i830}/i830_irq.c | 0 drivers/gpu/drm/i915/Makefile | 10 +++++ drivers/{char/drm => gpu/drm/i915}/i915_dma.c | 0 drivers/{char/drm => gpu/drm/i915}/i915_drv.c | 0 drivers/{char/drm => gpu/drm/i915}/i915_drv.h | 0 .../{char/drm => gpu/drm/i915}/i915_ioc32.c | 0 drivers/{char/drm => gpu/drm/i915}/i915_irq.c | 0 drivers/{char/drm => gpu/drm/i915}/i915_mem.c | 0 drivers/gpu/drm/mga/Makefile | 11 +++++ drivers/{char/drm => gpu/drm/mga}/mga_dma.c | 0 drivers/{char/drm => gpu/drm/mga}/mga_drv.c | 0 drivers/{char/drm => gpu/drm/mga}/mga_drv.h | 0 drivers/{char/drm => gpu/drm/mga}/mga_ioc32.c | 0 drivers/{char/drm => gpu/drm/mga}/mga_irq.c | 0 drivers/{char/drm => gpu/drm/mga}/mga_state.c | 0 drivers/{char/drm => gpu/drm/mga}/mga_ucode.h | 0 drivers/{char/drm => gpu/drm/mga}/mga_warp.c | 0 drivers/gpu/drm/r128/Makefile | 10 +++++ drivers/{char/drm => gpu/drm/r128}/r128_cce.c | 0 drivers/{char/drm => gpu/drm/r128}/r128_drv.c | 0 drivers/{char/drm => gpu/drm/r128}/r128_drv.h | 0 .../{char/drm => gpu/drm/r128}/r128_ioc32.c | 0 drivers/{char/drm => gpu/drm/r128}/r128_irq.c | 0 .../{char/drm => gpu/drm/r128}/r128_state.c | 0 drivers/gpu/drm/radeon/Makefile | 10 +++++ .../drm => gpu/drm/radeon}/r300_cmdbuf.c | 0 .../{char/drm => gpu/drm/radeon}/r300_reg.h | 0 .../{char/drm => gpu/drm/radeon}/radeon_cp.c | 0 .../{char/drm => gpu/drm/radeon}/radeon_drv.c | 0 .../{char/drm => gpu/drm/radeon}/radeon_drv.h | 0 .../drm => gpu/drm/radeon}/radeon_ioc32.c | 0 .../{char/drm => gpu/drm/radeon}/radeon_irq.c | 0 .../{char/drm => gpu/drm/radeon}/radeon_mem.c | 0 .../drm => gpu/drm/radeon}/radeon_microcode.h | 0 .../drm => gpu/drm/radeon}/radeon_state.c | 0 drivers/gpu/drm/savage/Makefile | 9 +++++ .../{char/drm => gpu/drm/savage}/savage_bci.c | 0 .../{char/drm => gpu/drm/savage}/savage_drv.c | 0 .../{char/drm => gpu/drm/savage}/savage_drv.h | 0 .../drm => gpu/drm/savage}/savage_state.c | 0 drivers/gpu/drm/sis/Makefile | 10 +++++ drivers/{char/drm => gpu/drm/sis}/sis_drv.c | 0 drivers/{char/drm => gpu/drm/sis}/sis_drv.h | 0 drivers/{char/drm => gpu/drm/sis}/sis_mm.c | 0 drivers/gpu/drm/tdfx/Makefile | 8 ++++ drivers/{char/drm => gpu/drm/tdfx}/tdfx_drv.c | 0 drivers/{char/drm => gpu/drm/tdfx}/tdfx_drv.h | 0 drivers/gpu/drm/via/Makefile | 8 ++++ .../{char/drm => gpu/drm/via}/via_3d_reg.h | 0 drivers/{char/drm => gpu/drm/via}/via_dma.c | 0 .../{char/drm => gpu/drm/via}/via_dmablit.c | 0 .../{char/drm => gpu/drm/via}/via_dmablit.h | 0 drivers/{char/drm => gpu/drm/via}/via_drv.c | 0 drivers/{char/drm => gpu/drm/via}/via_drv.h | 0 drivers/{char/drm => gpu/drm/via}/via_irq.c | 0 drivers/{char/drm => gpu/drm/via}/via_map.c | 0 drivers/{char/drm => gpu/drm/via}/via_mm.c | 0 .../{char/drm => gpu/drm/via}/via_verifier.c | 0 .../{char/drm => gpu/drm/via}/via_verifier.h | 0 drivers/{char/drm => gpu/drm/via}/via_video.c | 0 drivers/video/Kconfig | 2 +- include/Kbuild | 1 + include/drm/Kbuild | 10 +++++ {drivers/char => include}/drm/drm.h | 0 {drivers/char => include}/drm/drmP.h | 0 {drivers/char => include}/drm/drm_core.h | 0 {drivers/char => include}/drm/drm_hashtab.h | 0 {drivers/char => include}/drm/drm_memory.h | 0 .../char => include}/drm/drm_memory_debug.h | 0 {drivers/char => include}/drm/drm_os_linux.h | 0 {drivers/char => include}/drm/drm_pciids.h | 0 {drivers/char => include}/drm/drm_sarea.h | 0 {drivers/char => include}/drm/drm_sman.h | 0 {drivers/char => include}/drm/i810_drm.h | 0 {drivers/char => include}/drm/i830_drm.h | 0 {drivers/char => include}/drm/i915_drm.h | 0 {drivers/char => include}/drm/mga_drm.h | 0 {drivers/char => include}/drm/r128_drm.h | 0 {drivers/char => include}/drm/radeon_drm.h | 0 {drivers/char => include}/drm/savage_drm.h | 0 {drivers/char => include}/drm/sis_drm.h | 0 {drivers/char => include}/drm/via_drm.h | 0 120 files changed, 132 insertions(+), 42 deletions(-) delete mode 100644 drivers/char/drm/Makefile create mode 100644 drivers/gpu/Makefile rename drivers/{char => gpu}/drm/Kconfig (100%) create mode 100644 drivers/gpu/drm/Makefile rename drivers/{char => gpu}/drm/README.drm (100%) rename drivers/{char => gpu}/drm/ati_pcigart.c (100%) rename drivers/{char => gpu}/drm/drm_agpsupport.c (100%) rename drivers/{char => gpu}/drm/drm_auth.c (100%) rename drivers/{char => gpu}/drm/drm_bufs.c (100%) rename drivers/{char => gpu}/drm/drm_context.c (100%) rename drivers/{char => gpu}/drm/drm_dma.c (100%) rename drivers/{char => gpu}/drm/drm_drawable.c (100%) rename drivers/{char => gpu}/drm/drm_drv.c (100%) rename drivers/{char => gpu}/drm/drm_fops.c (100%) rename drivers/{char => gpu}/drm/drm_hashtab.c (100%) rename drivers/{char => gpu}/drm/drm_ioc32.c (100%) rename drivers/{char => gpu}/drm/drm_ioctl.c (100%) rename drivers/{char => gpu}/drm/drm_irq.c (100%) rename drivers/{char => gpu}/drm/drm_lock.c (100%) rename drivers/{char => gpu}/drm/drm_memory.c (100%) rename drivers/{char => gpu}/drm/drm_mm.c (100%) rename drivers/{char => gpu}/drm/drm_pci.c (100%) rename drivers/{char => gpu}/drm/drm_proc.c (100%) rename drivers/{char => gpu}/drm/drm_scatter.c (100%) rename drivers/{char => gpu}/drm/drm_sman.c (100%) rename drivers/{char => gpu}/drm/drm_stub.c (100%) rename drivers/{char => gpu}/drm/drm_sysfs.c (100%) rename drivers/{char => gpu}/drm/drm_vm.c (100%) create mode 100644 drivers/gpu/drm/i810/Makefile rename drivers/{char/drm => gpu/drm/i810}/i810_dma.c (100%) rename drivers/{char/drm => gpu/drm/i810}/i810_drv.c (100%) rename drivers/{char/drm => gpu/drm/i810}/i810_drv.h (100%) create mode 100644 drivers/gpu/drm/i830/Makefile rename drivers/{char/drm => gpu/drm/i830}/i830_dma.c (100%) rename drivers/{char/drm => gpu/drm/i830}/i830_drv.c (100%) rename drivers/{char/drm => gpu/drm/i830}/i830_drv.h (100%) rename drivers/{char/drm => gpu/drm/i830}/i830_irq.c (100%) create mode 100644 drivers/gpu/drm/i915/Makefile rename drivers/{char/drm => gpu/drm/i915}/i915_dma.c (100%) rename drivers/{char/drm => gpu/drm/i915}/i915_drv.c (100%) rename drivers/{char/drm => gpu/drm/i915}/i915_drv.h (100%) rename drivers/{char/drm => gpu/drm/i915}/i915_ioc32.c (100%) rename drivers/{char/drm => gpu/drm/i915}/i915_irq.c (100%) rename drivers/{char/drm => gpu/drm/i915}/i915_mem.c (100%) create mode 100644 drivers/gpu/drm/mga/Makefile rename drivers/{char/drm => gpu/drm/mga}/mga_dma.c (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_drv.c (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_drv.h (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_ioc32.c (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_irq.c (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_state.c (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_ucode.h (100%) rename drivers/{char/drm => gpu/drm/mga}/mga_warp.c (100%) create mode 100644 drivers/gpu/drm/r128/Makefile rename drivers/{char/drm => gpu/drm/r128}/r128_cce.c (100%) rename drivers/{char/drm => gpu/drm/r128}/r128_drv.c (100%) rename drivers/{char/drm => gpu/drm/r128}/r128_drv.h (100%) rename drivers/{char/drm => gpu/drm/r128}/r128_ioc32.c (100%) rename drivers/{char/drm => gpu/drm/r128}/r128_irq.c (100%) rename drivers/{char/drm => gpu/drm/r128}/r128_state.c (100%) create mode 100644 drivers/gpu/drm/radeon/Makefile rename drivers/{char/drm => gpu/drm/radeon}/r300_cmdbuf.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/r300_reg.h (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_cp.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_drv.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_drv.h (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_ioc32.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_irq.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_mem.c (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_microcode.h (100%) rename drivers/{char/drm => gpu/drm/radeon}/radeon_state.c (100%) create mode 100644 drivers/gpu/drm/savage/Makefile rename drivers/{char/drm => gpu/drm/savage}/savage_bci.c (100%) rename drivers/{char/drm => gpu/drm/savage}/savage_drv.c (100%) rename drivers/{char/drm => gpu/drm/savage}/savage_drv.h (100%) rename drivers/{char/drm => gpu/drm/savage}/savage_state.c (100%) create mode 100644 drivers/gpu/drm/sis/Makefile rename drivers/{char/drm => gpu/drm/sis}/sis_drv.c (100%) rename drivers/{char/drm => gpu/drm/sis}/sis_drv.h (100%) rename drivers/{char/drm => gpu/drm/sis}/sis_mm.c (100%) create mode 100644 drivers/gpu/drm/tdfx/Makefile rename drivers/{char/drm => gpu/drm/tdfx}/tdfx_drv.c (100%) rename drivers/{char/drm => gpu/drm/tdfx}/tdfx_drv.h (100%) create mode 100644 drivers/gpu/drm/via/Makefile rename drivers/{char/drm => gpu/drm/via}/via_3d_reg.h (100%) rename drivers/{char/drm => gpu/drm/via}/via_dma.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_dmablit.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_dmablit.h (100%) rename drivers/{char/drm => gpu/drm/via}/via_drv.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_drv.h (100%) rename drivers/{char/drm => gpu/drm/via}/via_irq.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_map.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_mm.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_verifier.c (100%) rename drivers/{char/drm => gpu/drm/via}/via_verifier.h (100%) rename drivers/{char/drm => gpu/drm/via}/via_video.c (100%) create mode 100644 include/drm/Kbuild rename {drivers/char => include}/drm/drm.h (100%) rename {drivers/char => include}/drm/drmP.h (100%) rename {drivers/char => include}/drm/drm_core.h (100%) rename {drivers/char => include}/drm/drm_hashtab.h (100%) rename {drivers/char => include}/drm/drm_memory.h (100%) rename {drivers/char => include}/drm/drm_memory_debug.h (100%) rename {drivers/char => include}/drm/drm_os_linux.h (100%) rename {drivers/char => include}/drm/drm_pciids.h (100%) rename {drivers/char => include}/drm/drm_sarea.h (100%) rename {drivers/char => include}/drm/drm_sman.h (100%) rename {drivers/char => include}/drm/i810_drm.h (100%) rename {drivers/char => include}/drm/i830_drm.h (100%) rename {drivers/char => include}/drm/i915_drm.h (100%) rename {drivers/char => include}/drm/mga_drm.h (100%) rename {drivers/char => include}/drm/r128_drm.h (100%) rename {drivers/char => include}/drm/radeon_drm.h (100%) rename {drivers/char => include}/drm/savage_drm.h (100%) rename {drivers/char => include}/drm/sis_drm.h (100%) rename {drivers/char => include}/drm/via_drm.h (100%) diff --git a/drivers/Makefile b/drivers/Makefile index f65deda72d6..fda44679dff 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 4c1c584e9eb..81630a68475 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/Makefile b/drivers/char/drm/Makefile deleted file mode 100644 index 1283ded88ea..00000000000 --- 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/gpu/Makefile b/drivers/gpu/Makefile new file mode 100644 index 00000000000..de566cf0414 --- /dev/null +++ b/drivers/gpu/Makefile @@ -0,0 +1 @@ +obj-y += drm/ diff --git a/drivers/char/drm/Kconfig b/drivers/gpu/drm/Kconfig similarity index 100% rename from drivers/char/drm/Kconfig rename to drivers/gpu/drm/Kconfig diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile new file mode 100644 index 00000000000..e9f9a97ae00 --- /dev/null +++ b/drivers/gpu/drm/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm + +drm-y := 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 + +drm-$(CONFIG_COMPAT) += drm_ioc32.o + +obj-$(CONFIG_DRM) += drm.o +obj-$(CONFIG_DRM_TDFX) += tdfx/ +obj-$(CONFIG_DRM_R128) += r128/ +obj-$(CONFIG_DRM_RADEON)+= radeon/ +obj-$(CONFIG_DRM_MGA) += mga/ +obj-$(CONFIG_DRM_I810) += i810/ +obj-$(CONFIG_DRM_I830) += i830/ +obj-$(CONFIG_DRM_I915) += i915/ +obj-$(CONFIG_DRM_SIS) += sis/ +obj-$(CONFIG_DRM_SAVAGE)+= savage/ +obj-$(CONFIG_DRM_VIA) +=via/ + diff --git a/drivers/char/drm/README.drm b/drivers/gpu/drm/README.drm similarity index 100% rename from drivers/char/drm/README.drm rename to drivers/gpu/drm/README.drm diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c similarity index 100% rename from drivers/char/drm/ati_pcigart.c rename to drivers/gpu/drm/ati_pcigart.c diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c similarity index 100% rename from drivers/char/drm/drm_agpsupport.c rename to drivers/gpu/drm/drm_agpsupport.c diff --git a/drivers/char/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c similarity index 100% rename from drivers/char/drm/drm_auth.c rename to drivers/gpu/drm/drm_auth.c diff --git a/drivers/char/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c similarity index 100% rename from drivers/char/drm/drm_bufs.c rename to drivers/gpu/drm/drm_bufs.c diff --git a/drivers/char/drm/drm_context.c b/drivers/gpu/drm/drm_context.c similarity index 100% rename from drivers/char/drm/drm_context.c rename to drivers/gpu/drm/drm_context.c diff --git a/drivers/char/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c similarity index 100% rename from drivers/char/drm/drm_dma.c rename to drivers/gpu/drm/drm_dma.c diff --git a/drivers/char/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c similarity index 100% rename from drivers/char/drm/drm_drawable.c rename to drivers/gpu/drm/drm_drawable.c diff --git a/drivers/char/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c similarity index 100% rename from drivers/char/drm/drm_drv.c rename to drivers/gpu/drm/drm_drv.c diff --git a/drivers/char/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c similarity index 100% rename from drivers/char/drm/drm_fops.c rename to drivers/gpu/drm/drm_fops.c diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c similarity index 100% rename from drivers/char/drm/drm_hashtab.c rename to drivers/gpu/drm/drm_hashtab.c diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c similarity index 100% rename from drivers/char/drm/drm_ioc32.c rename to drivers/gpu/drm/drm_ioc32.c diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c similarity index 100% rename from drivers/char/drm/drm_ioctl.c rename to drivers/gpu/drm/drm_ioctl.c diff --git a/drivers/char/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c similarity index 100% rename from drivers/char/drm/drm_irq.c rename to drivers/gpu/drm/drm_irq.c diff --git a/drivers/char/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c similarity index 100% rename from drivers/char/drm/drm_lock.c rename to drivers/gpu/drm/drm_lock.c diff --git a/drivers/char/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c similarity index 100% rename from drivers/char/drm/drm_memory.c rename to drivers/gpu/drm/drm_memory.c diff --git a/drivers/char/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c similarity index 100% rename from drivers/char/drm/drm_mm.c rename to drivers/gpu/drm/drm_mm.c diff --git a/drivers/char/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c similarity index 100% rename from drivers/char/drm/drm_pci.c rename to drivers/gpu/drm/drm_pci.c diff --git a/drivers/char/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c similarity index 100% rename from drivers/char/drm/drm_proc.c rename to drivers/gpu/drm/drm_proc.c diff --git a/drivers/char/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c similarity index 100% rename from drivers/char/drm/drm_scatter.c rename to drivers/gpu/drm/drm_scatter.c diff --git a/drivers/char/drm/drm_sman.c b/drivers/gpu/drm/drm_sman.c similarity index 100% rename from drivers/char/drm/drm_sman.c rename to drivers/gpu/drm/drm_sman.c diff --git a/drivers/char/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c similarity index 100% rename from drivers/char/drm/drm_stub.c rename to drivers/gpu/drm/drm_stub.c diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c similarity index 100% rename from drivers/char/drm/drm_sysfs.c rename to drivers/gpu/drm/drm_sysfs.c diff --git a/drivers/char/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c similarity index 100% rename from drivers/char/drm/drm_vm.c rename to drivers/gpu/drm/drm_vm.c diff --git a/drivers/gpu/drm/i810/Makefile b/drivers/gpu/drm/i810/Makefile new file mode 100644 index 00000000000..43844ecafcc --- /dev/null +++ b/drivers/gpu/drm/i810/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +i810-y := i810_drv.o i810_dma.o + +obj-$(CONFIG_DRM_I810) += i810.o diff --git a/drivers/char/drm/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c similarity index 100% rename from drivers/char/drm/i810_dma.c rename to drivers/gpu/drm/i810/i810_dma.c diff --git a/drivers/char/drm/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c similarity index 100% rename from drivers/char/drm/i810_drv.c rename to drivers/gpu/drm/i810/i810_drv.c diff --git a/drivers/char/drm/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h similarity index 100% rename from drivers/char/drm/i810_drv.h rename to drivers/gpu/drm/i810/i810_drv.h diff --git a/drivers/gpu/drm/i830/Makefile b/drivers/gpu/drm/i830/Makefile new file mode 100644 index 00000000000..c642ee0b238 --- /dev/null +++ b/drivers/gpu/drm/i830/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +i830-y := i830_drv.o i830_dma.o i830_irq.o + +obj-$(CONFIG_DRM_I830) += i830.o diff --git a/drivers/char/drm/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c similarity index 100% rename from drivers/char/drm/i830_dma.c rename to drivers/gpu/drm/i830/i830_dma.c diff --git a/drivers/char/drm/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c similarity index 100% rename from drivers/char/drm/i830_drv.c rename to drivers/gpu/drm/i830/i830_drv.c diff --git a/drivers/char/drm/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h similarity index 100% rename from drivers/char/drm/i830_drv.h rename to drivers/gpu/drm/i830/i830_drv.h diff --git a/drivers/char/drm/i830_irq.c b/drivers/gpu/drm/i830/i830_irq.c similarity index 100% rename from drivers/char/drm/i830_irq.c rename to drivers/gpu/drm/i830/i830_irq.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile new file mode 100644 index 00000000000..a9e60464df7 --- /dev/null +++ b/drivers/gpu/drm/i915/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o + +i915-$(CONFIG_COMPAT) += i915_ioc32.o + +obj-$(CONFIG_DRM_I915) += i915.o diff --git a/drivers/char/drm/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c similarity index 100% rename from drivers/char/drm/i915_dma.c rename to drivers/gpu/drm/i915/i915_dma.c diff --git a/drivers/char/drm/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c similarity index 100% rename from drivers/char/drm/i915_drv.c rename to drivers/gpu/drm/i915/i915_drv.c diff --git a/drivers/char/drm/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h similarity index 100% rename from drivers/char/drm/i915_drv.h rename to drivers/gpu/drm/i915/i915_drv.h diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c similarity index 100% rename from drivers/char/drm/i915_ioc32.c rename to drivers/gpu/drm/i915/i915_ioc32.c diff --git a/drivers/char/drm/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c similarity index 100% rename from drivers/char/drm/i915_irq.c rename to drivers/gpu/drm/i915/i915_irq.c diff --git a/drivers/char/drm/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c similarity index 100% rename from drivers/char/drm/i915_mem.c rename to drivers/gpu/drm/i915/i915_mem.c diff --git a/drivers/gpu/drm/mga/Makefile b/drivers/gpu/drm/mga/Makefile new file mode 100644 index 00000000000..60684785c20 --- /dev/null +++ b/drivers/gpu/drm/mga/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +mga-y := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o + +mga-$(CONFIG_COMPAT) += mga_ioc32.o + +obj-$(CONFIG_DRM_MGA) += mga.o + diff --git a/drivers/char/drm/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c similarity index 100% rename from drivers/char/drm/mga_dma.c rename to drivers/gpu/drm/mga/mga_dma.c diff --git a/drivers/char/drm/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c similarity index 100% rename from drivers/char/drm/mga_drv.c rename to drivers/gpu/drm/mga/mga_drv.c diff --git a/drivers/char/drm/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h similarity index 100% rename from drivers/char/drm/mga_drv.h rename to drivers/gpu/drm/mga/mga_drv.h diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c similarity index 100% rename from drivers/char/drm/mga_ioc32.c rename to drivers/gpu/drm/mga/mga_ioc32.c diff --git a/drivers/char/drm/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c similarity index 100% rename from drivers/char/drm/mga_irq.c rename to drivers/gpu/drm/mga/mga_irq.c diff --git a/drivers/char/drm/mga_state.c b/drivers/gpu/drm/mga/mga_state.c similarity index 100% rename from drivers/char/drm/mga_state.c rename to drivers/gpu/drm/mga/mga_state.c diff --git a/drivers/char/drm/mga_ucode.h b/drivers/gpu/drm/mga/mga_ucode.h similarity index 100% rename from drivers/char/drm/mga_ucode.h rename to drivers/gpu/drm/mga/mga_ucode.h diff --git a/drivers/char/drm/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c similarity index 100% rename from drivers/char/drm/mga_warp.c rename to drivers/gpu/drm/mga/mga_warp.c diff --git a/drivers/gpu/drm/r128/Makefile b/drivers/gpu/drm/r128/Makefile new file mode 100644 index 00000000000..1cc72ae3a88 --- /dev/null +++ b/drivers/gpu/drm/r128/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +r128-y := r128_drv.o r128_cce.o r128_state.o r128_irq.o + +r128-$(CONFIG_COMPAT) += r128_ioc32.o + +obj-$(CONFIG_DRM_R128) += r128.o diff --git a/drivers/char/drm/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c similarity index 100% rename from drivers/char/drm/r128_cce.c rename to drivers/gpu/drm/r128/r128_cce.c diff --git a/drivers/char/drm/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c similarity index 100% rename from drivers/char/drm/r128_drv.c rename to drivers/gpu/drm/r128/r128_drv.c diff --git a/drivers/char/drm/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h similarity index 100% rename from drivers/char/drm/r128_drv.h rename to drivers/gpu/drm/r128/r128_drv.h diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c similarity index 100% rename from drivers/char/drm/r128_ioc32.c rename to drivers/gpu/drm/r128/r128_ioc32.c diff --git a/drivers/char/drm/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c similarity index 100% rename from drivers/char/drm/r128_irq.c rename to drivers/gpu/drm/r128/r128_irq.c diff --git a/drivers/char/drm/r128_state.c b/drivers/gpu/drm/r128/r128_state.c similarity index 100% rename from drivers/char/drm/r128_state.c rename to drivers/gpu/drm/r128/r128_state.c diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile new file mode 100644 index 00000000000..feb521ebc39 --- /dev/null +++ b/drivers/gpu/drm/radeon/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o + +radeon-$(CONFIG_COMPAT) += radeon_ioc32.o + +obj-$(CONFIG_DRM_RADEON)+= radeon.o diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c similarity index 100% rename from drivers/char/drm/r300_cmdbuf.c rename to drivers/gpu/drm/radeon/r300_cmdbuf.c diff --git a/drivers/char/drm/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h similarity index 100% rename from drivers/char/drm/r300_reg.h rename to drivers/gpu/drm/radeon/r300_reg.h diff --git a/drivers/char/drm/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c similarity index 100% rename from drivers/char/drm/radeon_cp.c rename to drivers/gpu/drm/radeon/radeon_cp.c diff --git a/drivers/char/drm/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c similarity index 100% rename from drivers/char/drm/radeon_drv.c rename to drivers/gpu/drm/radeon/radeon_drv.c diff --git a/drivers/char/drm/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h similarity index 100% rename from drivers/char/drm/radeon_drv.h rename to drivers/gpu/drm/radeon/radeon_drv.h diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c similarity index 100% rename from drivers/char/drm/radeon_ioc32.c rename to drivers/gpu/drm/radeon/radeon_ioc32.c diff --git a/drivers/char/drm/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c similarity index 100% rename from drivers/char/drm/radeon_irq.c rename to drivers/gpu/drm/radeon/radeon_irq.c diff --git a/drivers/char/drm/radeon_mem.c b/drivers/gpu/drm/radeon/radeon_mem.c similarity index 100% rename from drivers/char/drm/radeon_mem.c rename to drivers/gpu/drm/radeon/radeon_mem.c diff --git a/drivers/char/drm/radeon_microcode.h b/drivers/gpu/drm/radeon/radeon_microcode.h similarity index 100% rename from drivers/char/drm/radeon_microcode.h rename to drivers/gpu/drm/radeon/radeon_microcode.h diff --git a/drivers/char/drm/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c similarity index 100% rename from drivers/char/drm/radeon_state.c rename to drivers/gpu/drm/radeon/radeon_state.c diff --git a/drivers/gpu/drm/savage/Makefile b/drivers/gpu/drm/savage/Makefile new file mode 100644 index 00000000000..d8f84ac7bb2 --- /dev/null +++ b/drivers/gpu/drm/savage/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y = -Iinclude/drm +savage-y := savage_drv.o savage_bci.o savage_state.o + +obj-$(CONFIG_DRM_SAVAGE)+= savage.o + diff --git a/drivers/char/drm/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c similarity index 100% rename from drivers/char/drm/savage_bci.c rename to drivers/gpu/drm/savage/savage_bci.c diff --git a/drivers/char/drm/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c similarity index 100% rename from drivers/char/drm/savage_drv.c rename to drivers/gpu/drm/savage/savage_drv.c diff --git a/drivers/char/drm/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h similarity index 100% rename from drivers/char/drm/savage_drv.h rename to drivers/gpu/drm/savage/savage_drv.h diff --git a/drivers/char/drm/savage_state.c b/drivers/gpu/drm/savage/savage_state.c similarity index 100% rename from drivers/char/drm/savage_state.c rename to drivers/gpu/drm/savage/savage_state.c diff --git a/drivers/gpu/drm/sis/Makefile b/drivers/gpu/drm/sis/Makefile new file mode 100644 index 00000000000..441c061c3ad --- /dev/null +++ b/drivers/gpu/drm/sis/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y = -Iinclude/drm +sis-y := sis_drv.o sis_mm.o + +obj-$(CONFIG_DRM_SIS) += sis.o + + diff --git a/drivers/char/drm/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c similarity index 100% rename from drivers/char/drm/sis_drv.c rename to drivers/gpu/drm/sis/sis_drv.c diff --git a/drivers/char/drm/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h similarity index 100% rename from drivers/char/drm/sis_drv.h rename to drivers/gpu/drm/sis/sis_drv.h diff --git a/drivers/char/drm/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c similarity index 100% rename from drivers/char/drm/sis_mm.c rename to drivers/gpu/drm/sis/sis_mm.c diff --git a/drivers/gpu/drm/tdfx/Makefile b/drivers/gpu/drm/tdfx/Makefile new file mode 100644 index 00000000000..0379f294b32 --- /dev/null +++ b/drivers/gpu/drm/tdfx/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +tdfx-y := tdfx_drv.o + +obj-$(CONFIG_DRM_TDFX) += tdfx.o diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c similarity index 100% rename from drivers/char/drm/tdfx_drv.c rename to drivers/gpu/drm/tdfx/tdfx_drv.c diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/gpu/drm/tdfx/tdfx_drv.h similarity index 100% rename from drivers/char/drm/tdfx_drv.h rename to drivers/gpu/drm/tdfx/tdfx_drv.h diff --git a/drivers/gpu/drm/via/Makefile b/drivers/gpu/drm/via/Makefile new file mode 100644 index 00000000000..d59e258e2c1 --- /dev/null +++ b/drivers/gpu/drm/via/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the drm device driver. This driver provides support for the +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. + +ccflags-y := -Iinclude/drm +via-y := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o + +obj-$(CONFIG_DRM_VIA) +=via.o diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/gpu/drm/via/via_3d_reg.h similarity index 100% rename from drivers/char/drm/via_3d_reg.h rename to drivers/gpu/drm/via/via_3d_reg.h diff --git a/drivers/char/drm/via_dma.c b/drivers/gpu/drm/via/via_dma.c similarity index 100% rename from drivers/char/drm/via_dma.c rename to drivers/gpu/drm/via/via_dma.c diff --git a/drivers/char/drm/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c similarity index 100% rename from drivers/char/drm/via_dmablit.c rename to drivers/gpu/drm/via/via_dmablit.c diff --git a/drivers/char/drm/via_dmablit.h b/drivers/gpu/drm/via/via_dmablit.h similarity index 100% rename from drivers/char/drm/via_dmablit.h rename to drivers/gpu/drm/via/via_dmablit.h diff --git a/drivers/char/drm/via_drv.c b/drivers/gpu/drm/via/via_drv.c similarity index 100% rename from drivers/char/drm/via_drv.c rename to drivers/gpu/drm/via/via_drv.c diff --git a/drivers/char/drm/via_drv.h b/drivers/gpu/drm/via/via_drv.h similarity index 100% rename from drivers/char/drm/via_drv.h rename to drivers/gpu/drm/via/via_drv.h diff --git a/drivers/char/drm/via_irq.c b/drivers/gpu/drm/via/via_irq.c similarity index 100% rename from drivers/char/drm/via_irq.c rename to drivers/gpu/drm/via/via_irq.c diff --git a/drivers/char/drm/via_map.c b/drivers/gpu/drm/via/via_map.c similarity index 100% rename from drivers/char/drm/via_map.c rename to drivers/gpu/drm/via/via_map.c diff --git a/drivers/char/drm/via_mm.c b/drivers/gpu/drm/via/via_mm.c similarity index 100% rename from drivers/char/drm/via_mm.c rename to drivers/gpu/drm/via/via_mm.c diff --git a/drivers/char/drm/via_verifier.c b/drivers/gpu/drm/via/via_verifier.c similarity index 100% rename from drivers/char/drm/via_verifier.c rename to drivers/gpu/drm/via/via_verifier.c diff --git a/drivers/char/drm/via_verifier.h b/drivers/gpu/drm/via/via_verifier.h similarity index 100% rename from drivers/char/drm/via_verifier.h rename to drivers/gpu/drm/via/via_verifier.h diff --git a/drivers/char/drm/via_video.c b/drivers/gpu/drm/via/via_video.c similarity index 100% rename from drivers/char/drm/via_video.c rename to drivers/gpu/drm/via/via_video.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e0c5f96b273..9b887ef64ff 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -7,7 +7,7 @@ menu "Graphics support" source "drivers/char/agp/Kconfig" -source "drivers/char/drm/Kconfig" +source "drivers/gpu/drm/Kconfig" config VGASTATE tristate diff --git a/include/Kbuild b/include/Kbuild index b5228877434..bdca155028e 100644 --- a/include/Kbuild +++ b/include/Kbuild @@ -4,5 +4,6 @@ header-y += sound/ header-y += mtd/ header-y += rdma/ header-y += video/ +header-y += drm/ header-y += asm-$(ARCH)/ diff --git a/include/drm/Kbuild b/include/drm/Kbuild new file mode 100644 index 00000000000..82b6983b7fb --- /dev/null +++ b/include/drm/Kbuild @@ -0,0 +1,10 @@ +unifdef-y += drm.h drm_sarea.h +unifdef-y += i810_drm.h +unifdef-y += i830_drm.h +unifdef-y += i915_drm.h +unifdef-y += mga_drm.h +unifdef-y += r128_drm.h +unifdef-y += radeon_drm.h +unifdef-y += sis_drm.h +unifdef-y += savage_drm.h +unifdef-y += via_drm.h diff --git a/drivers/char/drm/drm.h b/include/drm/drm.h similarity index 100% rename from drivers/char/drm/drm.h rename to include/drm/drm.h diff --git a/drivers/char/drm/drmP.h b/include/drm/drmP.h similarity index 100% rename from drivers/char/drm/drmP.h rename to include/drm/drmP.h diff --git a/drivers/char/drm/drm_core.h b/include/drm/drm_core.h similarity index 100% rename from drivers/char/drm/drm_core.h rename to include/drm/drm_core.h diff --git a/drivers/char/drm/drm_hashtab.h b/include/drm/drm_hashtab.h similarity index 100% rename from drivers/char/drm/drm_hashtab.h rename to include/drm/drm_hashtab.h diff --git a/drivers/char/drm/drm_memory.h b/include/drm/drm_memory.h similarity index 100% rename from drivers/char/drm/drm_memory.h rename to include/drm/drm_memory.h diff --git a/drivers/char/drm/drm_memory_debug.h b/include/drm/drm_memory_debug.h similarity index 100% rename from drivers/char/drm/drm_memory_debug.h rename to include/drm/drm_memory_debug.h diff --git a/drivers/char/drm/drm_os_linux.h b/include/drm/drm_os_linux.h similarity index 100% rename from drivers/char/drm/drm_os_linux.h rename to include/drm/drm_os_linux.h diff --git a/drivers/char/drm/drm_pciids.h b/include/drm/drm_pciids.h similarity index 100% rename from drivers/char/drm/drm_pciids.h rename to include/drm/drm_pciids.h diff --git a/drivers/char/drm/drm_sarea.h b/include/drm/drm_sarea.h similarity index 100% rename from drivers/char/drm/drm_sarea.h rename to include/drm/drm_sarea.h diff --git a/drivers/char/drm/drm_sman.h b/include/drm/drm_sman.h similarity index 100% rename from drivers/char/drm/drm_sman.h rename to include/drm/drm_sman.h diff --git a/drivers/char/drm/i810_drm.h b/include/drm/i810_drm.h similarity index 100% rename from drivers/char/drm/i810_drm.h rename to include/drm/i810_drm.h diff --git a/drivers/char/drm/i830_drm.h b/include/drm/i830_drm.h similarity index 100% rename from drivers/char/drm/i830_drm.h rename to include/drm/i830_drm.h diff --git a/drivers/char/drm/i915_drm.h b/include/drm/i915_drm.h similarity index 100% rename from drivers/char/drm/i915_drm.h rename to include/drm/i915_drm.h diff --git a/drivers/char/drm/mga_drm.h b/include/drm/mga_drm.h similarity index 100% rename from drivers/char/drm/mga_drm.h rename to include/drm/mga_drm.h diff --git a/drivers/char/drm/r128_drm.h b/include/drm/r128_drm.h similarity index 100% rename from drivers/char/drm/r128_drm.h rename to include/drm/r128_drm.h diff --git a/drivers/char/drm/radeon_drm.h b/include/drm/radeon_drm.h similarity index 100% rename from drivers/char/drm/radeon_drm.h rename to include/drm/radeon_drm.h diff --git a/drivers/char/drm/savage_drm.h b/include/drm/savage_drm.h similarity index 100% rename from drivers/char/drm/savage_drm.h rename to include/drm/savage_drm.h diff --git a/drivers/char/drm/sis_drm.h b/include/drm/sis_drm.h similarity index 100% rename from drivers/char/drm/sis_drm.h rename to include/drm/sis_drm.h diff --git a/drivers/char/drm/via_drm.h b/include/drm/via_drm.h similarity index 100% rename from drivers/char/drm/via_drm.h rename to include/drm/via_drm.h -- GitLab From 12b29f34558b9b45a2c6eabd4f3c6be939a3980f Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 7 May 2008 13:03:20 -0400 Subject: [PATCH 1705/2509] selinux: support deferred mapping of contexts Introduce SELinux support for deferred mapping of security contexts in the SID table upon policy reload, and use this support for inode security contexts when the context is not yet valid under the current policy. Only processes with CAP_MAC_ADMIN + mac_admin permission in policy can set undefined security contexts on inodes. Inodes with such undefined contexts are treated as having the unlabeled context until the context becomes valid upon a policy reload that defines the context. Context invalidation upon policy reload also uses this support to save the context information in the SID table and later recover it upon a subsequent policy reload that defines the context again. This support is to enable package managers and similar programs to set down file contexts unknown to the system policy at the time the file is created in order to better support placing loadable policy modules in packages and to support build systems that need to create images of different distro releases with different policies w/o requiring all of the contexts to be defined or legal in the build host policy. With this patch applied, the following sequence is possible, although in practice it is recommended that this permission only be allowed to specific program domains such as the package manager. # rmdir baz # rm bar # touch bar # chcon -t foo_exec_t bar # foo_exec_t is not yet defined chcon: failed to change context of `bar' to `system_u:object_r:foo_exec_t': Invalid argument # mkdir -Z system_u:object_r:foo_exec_t baz mkdir: failed to set default file creation context to `system_u:object_r:foo_exec_t': Invalid argument # cat setundefined.te policy_module(setundefined, 1.0) require { type unconfined_t; type unlabeled_t; } files_type(unlabeled_t) allow unconfined_t self:capability2 mac_admin; # make -f /usr/share/selinux/devel/Makefile setundefined.pp # semodule -i setundefined.pp # chcon -t foo_exec_t bar # foo_exec_t is not yet defined # mkdir -Z system_u:object_r:foo_exec_t baz # ls -Zd bar baz -rw-r--r-- root root system_u:object_r:unlabeled_t bar drwxr-xr-x root root system_u:object_r:unlabeled_t baz # cat foo.te policy_module(foo, 1.0) type foo_exec_t; files_type(foo_exec_t) # make -f /usr/share/selinux/devel/Makefile foo.pp # semodule -i foo.pp # defines foo_exec_t # ls -Zd bar baz -rw-r--r-- root root user_u:object_r:foo_exec_t bar drwxr-xr-x root root system_u:object_r:foo_exec_t baz # semodule -r foo # ls -Zd bar baz -rw-r--r-- root root system_u:object_r:unlabeled_t bar drwxr-xr-x root root system_u:object_r:unlabeled_t baz # semodule -i foo.pp # ls -Zd bar baz -rw-r--r-- root root user_u:object_r:foo_exec_t bar drwxr-xr-x root root system_u:object_r:foo_exec_t baz # semodule -r setundefined foo # chcon -t foo_exec_t bar # no longer defined and not allowed chcon: failed to change context of `bar' to `system_u:object_r:foo_exec_t': Invalid argument # rmdir baz # mkdir -Z system_u:object_r:foo_exec_t baz mkdir: failed to set default file creation context to `system_u:object_r:foo_exec_t': Invalid argument Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 20 ++- security/selinux/include/security.h | 5 + security/selinux/ss/context.h | 27 ++- security/selinux/ss/mls.c | 11 +- security/selinux/ss/mls.h | 3 +- security/selinux/ss/services.c | 245 ++++++++++++++++++++-------- security/selinux/ss/sidtab.c | 58 +++---- security/selinux/ss/sidtab.h | 7 +- 8 files changed, 248 insertions(+), 128 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1c864c0efe2..59c6e98f7be 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2495,7 +2495,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, } if (value && len) { - rc = security_sid_to_context(newsid, &context, &clen); + rc = security_sid_to_context_force(newsid, &context, &clen); if (rc) { kfree(namep); return rc; @@ -2669,6 +2669,11 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, return rc; rc = security_context_to_sid(value, size, &newsid); + if (rc == -EINVAL) { + if (!capable(CAP_MAC_ADMIN)) + return rc; + rc = security_context_to_sid_force(value, size, &newsid); + } if (rc) return rc; @@ -2703,10 +2708,11 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, return; } - rc = security_context_to_sid(value, size, &newsid); + rc = security_context_to_sid_force(value, size, &newsid); if (rc) { - printk(KERN_WARNING "%s: unable to obtain SID for context " - "%s, rc=%d\n", __func__, (char *)value, -rc); + printk(KERN_ERR "SELinux: unable to map context to SID" + "for (%s, %lu), rc=%d\n", + inode->i_sb->s_id, inode->i_ino, -rc); return; } @@ -5153,6 +5159,12 @@ static int selinux_setprocattr(struct task_struct *p, size--; } error = security_context_to_sid(value, size, &sid); + if (error == -EINVAL && !strcmp(name, "fscreate")) { + if (!capable(CAP_MAC_ADMIN)) + return error; + error = security_context_to_sid_force(value, size, + &sid); + } if (error) return error; } diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index ad30ac4273d..7c543003d65 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -93,12 +93,17 @@ int security_change_sid(u32 ssid, u32 tsid, int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len); +int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); + int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *out_sid); int security_context_to_sid_default(const char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid, gfp_t gfp_flags); +int security_context_to_sid_force(const char *scontext, u32 scontext_len, + u32 *sid); + int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel); diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index b9a6f7fc62f..658c2bd17da 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -28,6 +28,8 @@ struct context { u32 role; u32 type; struct mls_range range; + char *str; /* string representation if context cannot be mapped. */ + u32 len; /* length of string in bytes */ }; static inline void mls_context_init(struct context *c) @@ -106,20 +108,43 @@ static inline void context_init(struct context *c) static inline int context_cpy(struct context *dst, struct context *src) { + int rc; + dst->user = src->user; dst->role = src->role; dst->type = src->type; - return mls_context_cpy(dst, src); + if (src->str) { + dst->str = kstrdup(src->str, GFP_ATOMIC); + if (!dst->str) + return -ENOMEM; + dst->len = src->len; + } else { + dst->str = NULL; + dst->len = 0; + } + rc = mls_context_cpy(dst, src); + if (rc) { + kfree(dst->str); + return rc; + } + return 0; } static inline void context_destroy(struct context *c) { c->user = c->role = c->type = 0; + kfree(c->str); + c->str = NULL; + c->len = 0; mls_context_destroy(c); } static inline int context_cmp(struct context *c1, struct context *c2) { + if (c1->len && c2->len) + return (c1->len == c2->len && !strcmp(c1->str, c2->str)); + if (c1->len || c2->len) + return 0; return ((c1->user == c2->user) && (c1->role == c2->role) && (c1->type == c2->type) && diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 8b1706b7b3c..a6ca0587e63 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -239,7 +239,8 @@ int mls_context_isvalid(struct policydb *p, struct context *c) * Policy read-lock must be held for sidtab lookup. * */ -int mls_context_to_sid(char oldc, +int mls_context_to_sid(struct policydb *pol, + char oldc, char **scontext, struct context *context, struct sidtab *s, @@ -286,7 +287,7 @@ int mls_context_to_sid(char oldc, *p++ = 0; for (l = 0; l < 2; l++) { - levdatum = hashtab_search(policydb.p_levels.table, scontextp); + levdatum = hashtab_search(pol->p_levels.table, scontextp); if (!levdatum) { rc = -EINVAL; goto out; @@ -311,7 +312,7 @@ int mls_context_to_sid(char oldc, *rngptr++ = 0; } - catdatum = hashtab_search(policydb.p_cats.table, + catdatum = hashtab_search(pol->p_cats.table, scontextp); if (!catdatum) { rc = -EINVAL; @@ -327,7 +328,7 @@ int mls_context_to_sid(char oldc, if (rngptr) { int i; - rngdatum = hashtab_search(policydb.p_cats.table, rngptr); + rngdatum = hashtab_search(pol->p_cats.table, rngptr); if (!rngdatum) { rc = -EINVAL; goto out; @@ -395,7 +396,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) if (!tmpstr) { rc = -ENOMEM; } else { - rc = mls_context_to_sid(':', &tmpstr, context, + rc = mls_context_to_sid(&policydb, ':', &tmpstr, context, NULL, SECSID_NULL); kfree(freestr); } diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 0fdf6257ef6..1276715aaa8 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -30,7 +30,8 @@ int mls_context_isvalid(struct policydb *p, struct context *c); int mls_range_isvalid(struct policydb *p, struct mls_range *r); int mls_level_isvalid(struct policydb *p, struct mls_level *l); -int mls_context_to_sid(char oldc, +int mls_context_to_sid(struct policydb *p, + char oldc, char **scontext, struct context *context, struct sidtab *s, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index dcc2e1c4fd8..b86ac9da6cf 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -616,6 +616,14 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 *scontext = NULL; *scontext_len = 0; + if (context->len) { + *scontext_len = context->len; + *scontext = kstrdup(context->str, GFP_ATOMIC); + if (!(*scontext)) + return -ENOMEM; + return 0; + } + /* Compute the size of the context. */ *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; @@ -655,17 +663,8 @@ const char *security_get_initial_sid_context(u32 sid) return initial_sid_to_string[sid]; } -/** - * security_sid_to_context - Obtain a context for a given SID. - * @sid: security identifier, SID - * @scontext: security context - * @scontext_len: length in bytes - * - * Write the string representation of the context associated with @sid - * into a dynamically allocated string of the correct size. Set @scontext - * to point to this string and set @scontext_len to the length of the string. - */ -int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) +static int security_sid_to_context_core(u32 sid, char **scontext, + u32 *scontext_len, int force) { struct context *context; int rc = 0; @@ -693,7 +692,10 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) goto out; } POLICY_RDLOCK; - context = sidtab_search(&sidtab, sid); + if (force) + context = sidtab_search_force(&sidtab, sid); + else + context = sidtab_search(&sidtab, sid); if (!context) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", __func__, sid); @@ -708,36 +710,44 @@ out: } -static int security_context_to_sid_core(const char *scontext, u32 scontext_len, - u32 *sid, u32 def_sid, gfp_t gfp_flags) +/** + * security_sid_to_context - Obtain a context for a given SID. + * @sid: security identifier, SID + * @scontext: security context + * @scontext_len: length in bytes + * + * Write the string representation of the context associated with @sid + * into a dynamically allocated string of the correct size. Set @scontext + * to point to this string and set @scontext_len to the length of the string. + */ +int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) { - char *scontext2; - struct context context; + return security_sid_to_context_core(sid, scontext, scontext_len, 0); +} + +int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len) +{ + return security_sid_to_context_core(sid, scontext, scontext_len, 1); +} + +static int string_to_context_struct(struct policydb *pol, + struct sidtab *sidtabp, + const char *scontext, + u32 scontext_len, + struct context *ctx, + u32 def_sid, + gfp_t gfp_flags) +{ + char *scontext2 = NULL; struct role_datum *role; struct type_datum *typdatum; struct user_datum *usrdatum; char *scontextp, *p, oldc; int rc = 0; - if (!ss_initialized) { - int i; + context_init(ctx); - for (i = 1; i < SECINITSID_NUM; i++) { - if (!strcmp(initial_sid_to_string[i], scontext)) { - *sid = i; - goto out; - } - } - *sid = SECINITSID_KERNEL; - goto out; - } - *sid = SECSID_NULL; - - /* Copy the string so that we can modify the copy as we parse it. - The string should already by null terminated, but we append a - null suffix to the copy to avoid problems with the existing - attr package, which doesn't view the null terminator as part - of the attribute value. */ + /* Copy the string so that we can modify the copy as we parse it. */ scontext2 = kmalloc(scontext_len+1, gfp_flags); if (!scontext2) { rc = -ENOMEM; @@ -746,11 +756,6 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, memcpy(scontext2, scontext, scontext_len); scontext2[scontext_len] = 0; - context_init(&context); - *sid = SECSID_NULL; - - POLICY_RDLOCK; - /* Parse the security context. */ rc = -EINVAL; @@ -762,15 +767,15 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, p++; if (*p == 0) - goto out_unlock; + goto out; *p++ = 0; - usrdatum = hashtab_search(policydb.p_users.table, scontextp); + usrdatum = hashtab_search(pol->p_users.table, scontextp); if (!usrdatum) - goto out_unlock; + goto out; - context.user = usrdatum->value; + ctx->user = usrdatum->value; /* Extract role. */ scontextp = p; @@ -778,14 +783,14 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, p++; if (*p == 0) - goto out_unlock; + goto out; *p++ = 0; - role = hashtab_search(policydb.p_roles.table, scontextp); + role = hashtab_search(pol->p_roles.table, scontextp); if (!role) - goto out_unlock; - context.role = role->value; + goto out; + ctx->role = role->value; /* Extract type. */ scontextp = p; @@ -794,33 +799,74 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, oldc = *p; *p++ = 0; - typdatum = hashtab_search(policydb.p_types.table, scontextp); + typdatum = hashtab_search(pol->p_types.table, scontextp); if (!typdatum) - goto out_unlock; + goto out; - context.type = typdatum->value; + ctx->type = typdatum->value; - rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); + rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid); if (rc) - goto out_unlock; + goto out; if ((p - scontext2) < scontext_len) { rc = -EINVAL; - goto out_unlock; + goto out; } /* Check the validity of the new context. */ - if (!policydb_context_isvalid(&policydb, &context)) { + if (!policydb_context_isvalid(pol, ctx)) { rc = -EINVAL; - goto out_unlock; + context_destroy(ctx); + goto out; } - /* Obtain the new sid. */ - rc = sidtab_context_to_sid(&sidtab, &context, sid); -out_unlock: - POLICY_RDUNLOCK; - context_destroy(&context); + rc = 0; +out: kfree(scontext2); + return rc; +} + +static int security_context_to_sid_core(const char *scontext, u32 scontext_len, + u32 *sid, u32 def_sid, gfp_t gfp_flags, + int force) +{ + struct context context; + int rc = 0; + + if (!ss_initialized) { + int i; + + for (i = 1; i < SECINITSID_NUM; i++) { + if (!strcmp(initial_sid_to_string[i], scontext)) { + *sid = i; + goto out; + } + } + *sid = SECINITSID_KERNEL; + goto out; + } + *sid = SECSID_NULL; + + POLICY_RDLOCK; + rc = string_to_context_struct(&policydb, &sidtab, + scontext, scontext_len, + &context, def_sid, gfp_flags); + if (rc == -EINVAL && force) { + context.str = kmalloc(scontext_len+1, gfp_flags); + if (!context.str) { + rc = -ENOMEM; + goto out; + } + memcpy(context.str, scontext, scontext_len); + context.str[scontext_len] = 0; + context.len = scontext_len; + } else if (rc) + goto out; + rc = sidtab_context_to_sid(&sidtab, &context, sid); + if (rc) + context_destroy(&context); out: + POLICY_RDUNLOCK; return rc; } @@ -838,7 +884,7 @@ out: int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) { return security_context_to_sid_core(scontext, scontext_len, - sid, SECSID_NULL, GFP_KERNEL); + sid, SECSID_NULL, GFP_KERNEL, 0); } /** @@ -855,6 +901,7 @@ int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) * The default SID is passed to the MLS layer to be used to allow * kernel labeling of the MLS field if the MLS field is not present * (for upgrading to MLS without full relabel). + * Implicitly forces adding of the context even if it cannot be mapped yet. * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */ @@ -862,7 +909,14 @@ int security_context_to_sid_default(const char *scontext, u32 scontext_len, u32 *sid, u32 def_sid, gfp_t gfp_flags) { return security_context_to_sid_core(scontext, scontext_len, - sid, def_sid, gfp_flags); + sid, def_sid, gfp_flags, 1); +} + +int security_context_to_sid_force(const char *scontext, u32 scontext_len, + u32 *sid) +{ + return security_context_to_sid_core(scontext, scontext_len, + sid, SECSID_NULL, GFP_KERNEL, 1); } static int compute_sid_handle_invalid_context( @@ -1246,9 +1300,12 @@ static inline int convert_context_handle_invalid_context(struct context *context char *s; u32 len; - context_struct_to_string(context, &s, &len); - printk(KERN_ERR "SELinux: context %s is invalid\n", s); - kfree(s); + if (!context_struct_to_string(context, &s, &len)) { + printk(KERN_WARNING + "SELinux: Context %s would be invalid if enforcing\n", + s); + kfree(s); + } } return rc; } @@ -1280,6 +1337,32 @@ static int convert_context(u32 key, args = p; + if (c->str) { + struct context ctx; + rc = string_to_context_struct(args->newp, NULL, c->str, + c->len, &ctx, SECSID_NULL, + GFP_KERNEL); + if (!rc) { + printk(KERN_INFO + "SELinux: Context %s became valid (mapped).\n", + c->str); + /* Replace string with mapped representation. */ + kfree(c->str); + memcpy(c, &ctx, sizeof(*c)); + goto out; + } else if (rc == -EINVAL) { + /* Retain string representation for later mapping. */ + rc = 0; + goto out; + } else { + /* Other error condition, e.g. ENOMEM. */ + printk(KERN_ERR + "SELinux: Unable to map context %s, rc = %d.\n", + c->str, -rc); + goto out; + } + } + rc = context_cpy(&oldc, c); if (rc) goto out; @@ -1319,13 +1402,21 @@ static int convert_context(u32 key, } context_destroy(&oldc); + rc = 0; out: return rc; bad: - context_struct_to_string(&oldc, &s, &len); + /* Map old representation to string and save it. */ + if (context_struct_to_string(&oldc, &s, &len)) + return -ENOMEM; context_destroy(&oldc); - printk(KERN_ERR "SELinux: invalidating context %s\n", s); - kfree(s); + context_destroy(c); + c->str = s; + c->len = len; + printk(KERN_INFO + "SELinux: Context %s became invalid (unmapped).\n", + c->str); + rc = 0; goto out; } @@ -1406,7 +1497,11 @@ int security_load_policy(void *data, size_t len) return -EINVAL; } - sidtab_init(&newsidtab); + if (sidtab_init(&newsidtab)) { + LOAD_UNLOCK; + policydb_destroy(&newpolicydb); + return -ENOMEM; + } /* Verify that the kernel defined classes are correct. */ if (validate_classes(&newpolicydb)) { @@ -1429,11 +1524,15 @@ int security_load_policy(void *data, size_t len) goto err; } - /* Convert the internal representations of contexts - in the new SID table and remove invalid SIDs. */ + /* + * Convert the internal representations of contexts + * in the new SID table. + */ args.oldp = &policydb; args.newp = &newpolicydb; - sidtab_map_remove_on_error(&newsidtab, convert_context, &args); + rc = sidtab_map(&newsidtab, convert_context, &args); + if (rc) + goto err; /* Save the old policydb and SID table to free later. */ memcpy(&oldpolicydb, &policydb, sizeof policydb); @@ -1673,6 +1772,8 @@ int security_get_user_sids(u32 fromsid, POLICY_RDLOCK; + context_init(&usercon); + fromcon = sidtab_search(&sidtab, fromsid); if (!fromcon) { rc = -EINVAL; diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 4a516ff4bcd..ba354164049 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -86,7 +86,7 @@ out: return rc; } -struct context *sidtab_search(struct sidtab *s, u32 sid) +static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) { int hvalue; struct sidtab_node *cur; @@ -99,7 +99,10 @@ struct context *sidtab_search(struct sidtab *s, u32 sid) while (cur != NULL && sid > cur->sid) cur = cur->next; - if (cur == NULL || sid != cur->sid) { + if (force && cur && sid == cur->sid && cur->context.len) + return &cur->context; + + if (cur == NULL || sid != cur->sid || cur->context.len) { /* Remap invalid SIDs to the unlabeled SID. */ sid = SECINITSID_UNLABELED; hvalue = SIDTAB_HASH(sid); @@ -113,6 +116,16 @@ struct context *sidtab_search(struct sidtab *s, u32 sid) return &cur->context; } +struct context *sidtab_search(struct sidtab *s, u32 sid) +{ + return sidtab_search_core(s, sid, 0); +} + +struct context *sidtab_search_force(struct sidtab *s, u32 sid) +{ + return sidtab_search_core(s, sid, 1); +} + int sidtab_map(struct sidtab *s, int (*apply) (u32 sid, struct context *context, @@ -138,43 +151,6 @@ out: return rc; } -void sidtab_map_remove_on_error(struct sidtab *s, - int (*apply) (u32 sid, - struct context *context, - void *args), - void *args) -{ - int i, ret; - struct sidtab_node *last, *cur, *temp; - - if (!s) - return; - - for (i = 0; i < SIDTAB_SIZE; i++) { - last = NULL; - cur = s->htable[i]; - while (cur != NULL) { - ret = apply(cur->sid, &cur->context, args); - if (ret) { - if (last) - last->next = cur->next; - else - s->htable[i] = cur->next; - temp = cur; - cur = cur->next; - context_destroy(&temp->context); - kfree(temp); - s->nel--; - } else { - last = cur; - cur = cur->next; - } - } - } - - return; -} - static inline u32 sidtab_search_context(struct sidtab *s, struct context *context) { @@ -215,6 +191,10 @@ int sidtab_context_to_sid(struct sidtab *s, goto unlock_out; } sid = s->next_sid++; + if (context->len) + printk(KERN_INFO + "SELinux: Context %s is not valid (left unmapped).\n", + context->str); ret = sidtab_insert(s, sid, context); if (ret) s->next_sid--; diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 2fe9dfa3eb3..64ea5b1cdea 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -32,6 +32,7 @@ struct sidtab { int sidtab_init(struct sidtab *s); int sidtab_insert(struct sidtab *s, u32 sid, struct context *context); struct context *sidtab_search(struct sidtab *s, u32 sid); +struct context *sidtab_search_force(struct sidtab *s, u32 sid); int sidtab_map(struct sidtab *s, int (*apply) (u32 sid, @@ -39,12 +40,6 @@ int sidtab_map(struct sidtab *s, void *args), void *args); -void sidtab_map_remove_on_error(struct sidtab *s, - int (*apply) (u32 sid, - struct context *context, - void *args), - void *args); - int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); -- GitLab From 9a59daa03df72526d234b91dd3e32ded5aebd3ef Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 14 May 2008 10:33:55 -0400 Subject: [PATCH 1706/2509] SELinux: fix sleeping allocation in security_context_to_sid Fix a sleeping function called from invalid context bug by moving allocation to the callers prior to taking the policy rdlock. Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/ss/services.c | 70 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b86ac9da6cf..2d5e5a3a8aa 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -730,15 +730,16 @@ int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len) return security_sid_to_context_core(sid, scontext, scontext_len, 1); } +/* + * Caveat: Mutates scontext. + */ static int string_to_context_struct(struct policydb *pol, struct sidtab *sidtabp, - const char *scontext, + char *scontext, u32 scontext_len, struct context *ctx, - u32 def_sid, - gfp_t gfp_flags) + u32 def_sid) { - char *scontext2 = NULL; struct role_datum *role; struct type_datum *typdatum; struct user_datum *usrdatum; @@ -747,19 +748,10 @@ static int string_to_context_struct(struct policydb *pol, context_init(ctx); - /* Copy the string so that we can modify the copy as we parse it. */ - scontext2 = kmalloc(scontext_len+1, gfp_flags); - if (!scontext2) { - rc = -ENOMEM; - goto out; - } - memcpy(scontext2, scontext, scontext_len); - scontext2[scontext_len] = 0; - /* Parse the security context. */ rc = -EINVAL; - scontextp = (char *) scontext2; + scontextp = (char *) scontext; /* Extract the user. */ p = scontextp; @@ -809,7 +801,7 @@ static int string_to_context_struct(struct policydb *pol, if (rc) goto out; - if ((p - scontext2) < scontext_len) { + if ((p - scontext) < scontext_len) { rc = -EINVAL; goto out; } @@ -822,7 +814,6 @@ static int string_to_context_struct(struct policydb *pol, } rc = 0; out: - kfree(scontext2); return rc; } @@ -830,6 +821,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, u32 *sid, u32 def_sid, gfp_t gfp_flags, int force) { + char *scontext2, *str = NULL; struct context context; int rc = 0; @@ -839,27 +831,38 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, for (i = 1; i < SECINITSID_NUM; i++) { if (!strcmp(initial_sid_to_string[i], scontext)) { *sid = i; - goto out; + return 0; } } *sid = SECINITSID_KERNEL; - goto out; + return 0; } *sid = SECSID_NULL; + /* Copy the string so that we can modify the copy as we parse it. */ + scontext2 = kmalloc(scontext_len+1, gfp_flags); + if (!scontext2) + return -ENOMEM; + memcpy(scontext2, scontext, scontext_len); + scontext2[scontext_len] = 0; + + if (force) { + /* Save another copy for storing in uninterpreted form */ + str = kstrdup(scontext2, gfp_flags); + if (!str) { + kfree(scontext2); + return -ENOMEM; + } + } + POLICY_RDLOCK; rc = string_to_context_struct(&policydb, &sidtab, - scontext, scontext_len, - &context, def_sid, gfp_flags); + scontext2, scontext_len, + &context, def_sid); if (rc == -EINVAL && force) { - context.str = kmalloc(scontext_len+1, gfp_flags); - if (!context.str) { - rc = -ENOMEM; - goto out; - } - memcpy(context.str, scontext, scontext_len); - context.str[scontext_len] = 0; + context.str = str; context.len = scontext_len; + str = NULL; } else if (rc) goto out; rc = sidtab_context_to_sid(&sidtab, &context, sid); @@ -867,6 +870,8 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, context_destroy(&context); out: POLICY_RDUNLOCK; + kfree(scontext2); + kfree(str); return rc; } @@ -1339,9 +1344,14 @@ static int convert_context(u32 key, if (c->str) { struct context ctx; - rc = string_to_context_struct(args->newp, NULL, c->str, - c->len, &ctx, SECSID_NULL, - GFP_KERNEL); + s = kstrdup(c->str, GFP_KERNEL); + if (!s) { + rc = -ENOMEM; + goto out; + } + rc = string_to_context_struct(args->newp, NULL, s, + c->len, &ctx, SECSID_NULL); + kfree(s); if (!rc) { printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n", -- GitLab From f5269710789f666a65cf1132c4f1d14fbc8d3c29 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 14 May 2008 11:27:45 -0400 Subject: [PATCH 1707/2509] SELinux: keep the code clean formating and syntax Formatting and syntax changes whitespace, tabs to spaces, trailing space put open { on same line as struct def remove unneeded {} after if statements change printk("Lu") to printk("llu") convert asm/uaccess.h to linux/uaacess.h includes remove unnecessary asm/bug.h includes convert all users of simple_strtol to strict_strtol Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/hooks.c | 18 +++++++++++------- security/selinux/include/audit.h | 4 ++-- security/selinux/include/avc.h | 15 +++++++-------- security/selinux/netnode.c | 1 - security/selinux/netport.c | 3 +-- security/selinux/selinuxfs.c | 10 +++++++--- security/selinux/ss/avtab.c | 2 +- security/selinux/ss/mls.c | 8 ++++---- security/selinux/ss/services.c | 4 ++-- 9 files changed, 35 insertions(+), 30 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 59c6e98f7be..eca70f42e67 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -53,7 +53,7 @@ #include /* struct or_callable used in sock_rcv_skb */ #include #include -#include +#include #include #include #include @@ -104,7 +104,9 @@ int selinux_enforcing; static int __init enforcing_setup(char *str) { - selinux_enforcing = simple_strtol(str, NULL, 0); + unsigned long enforcing; + if (!strict_strtoul(str, 0, &enforcing)) + selinux_enforcing = enforcing ? 1 : 0; return 1; } __setup("enforcing=", enforcing_setup); @@ -115,7 +117,9 @@ int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; static int __init selinux_enabled_setup(char *str) { - selinux_enabled = simple_strtol(str, NULL, 0); + unsigned long enabled; + if (!strict_strtoul(str, 0, &enabled)) + selinux_enabled = enabled ? 1 : 0; return 1; } __setup("selinux=", selinux_enabled_setup); @@ -594,7 +598,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, */ if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) && (num_opts == 0)) - goto out; + goto out; /* * parse the mount options, check if they are valid sids. @@ -2695,7 +2699,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, } static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, + const void *value, size_t size, int flags) { struct inode *inode = dentry->d_inode; @@ -5390,7 +5394,7 @@ static struct security_operations selinux_ops = { .inode_listsecurity = selinux_inode_listsecurity, .inode_need_killpriv = selinux_inode_need_killpriv, .inode_killpriv = selinux_inode_killpriv, - .inode_getsecid = selinux_inode_getsecid, + .inode_getsecid = selinux_inode_getsecid, .file_permission = selinux_file_permission, .file_alloc_security = selinux_file_alloc_security, @@ -5431,7 +5435,7 @@ static struct security_operations selinux_ops = { .task_to_inode = selinux_task_to_inode, .ipc_permission = selinux_ipc_permission, - .ipc_getsecid = selinux_ipc_getsecid, + .ipc_getsecid = selinux_ipc_getsecid, .msg_msg_alloc_security = selinux_msg_msg_alloc_security, .msg_msg_free_security = selinux_msg_msg_free_security, diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index 6c8b9ef1557..1bdf973433c 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h @@ -1,7 +1,7 @@ /* * SELinux support for the Audit LSM hooks * - * Most of below header was moved from include/linux/selinux.h which + * Most of below header was moved from include/linux/selinux.h which * is released under below copyrights: * * Author: James Morris @@ -52,7 +52,7 @@ void selinux_audit_rule_free(void *rule); * -errno on failure. */ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, - struct audit_context *actx); + struct audit_context *actx); /** * selinux_audit_rule_known - check to see if rule contains selinux fields. diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 8e23d7a873a..7b9769f5e77 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -75,13 +75,12 @@ struct avc_audit_data { /* Initialize an AVC audit data structure. */ #define AVC_AUDIT_DATA_INIT(_d,_t) \ - { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; } + { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; } /* * AVC statistics */ -struct avc_cache_stats -{ +struct avc_cache_stats { unsigned int lookups; unsigned int hits; unsigned int misses; @@ -97,8 +96,8 @@ struct avc_cache_stats void __init avc_init(void); void avc_audit(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct av_decision *avd, int result, struct avc_audit_data *auditdata); + u16 tclass, u32 requested, + struct av_decision *avd, int result, struct avc_audit_data *auditdata); #define AVC_STRICT 1 /* Ignore permissive mode. */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, @@ -107,8 +106,8 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, struct av_decision *avd); int avc_has_perm(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct avc_audit_data *auditdata); + u16 tclass, u32 requested, + struct avc_audit_data *auditdata); u32 avc_policy_seqno(void); @@ -122,7 +121,7 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_AUDITDENY_DISABLE 128 int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, - u16 tclass, u32 perms, + u16 tclass, u32 perms, u32 *out_retained), u32 events, u32 ssid, u32 tsid, u16 tclass, u32 perms); diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index b6ccd09379f..7100072bb1b 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "netnode.h" #include "objsec.h" diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 90b4cff7c35..fe7fba67f19 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -37,7 +37,6 @@ #include #include #include -#include #include "netport.h" #include "objsec.h" @@ -272,7 +271,7 @@ static __init int sel_netport_init(void) } ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET, - SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (ret != 0) panic("avc_add_callback() failed, error %d\n", ret); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index ac1ccc13a70..07a5db69571 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include /* selinuxfs pseudo filesystem for exporting the security policy API. Based on the proc code and the fs/nfsd/nfsctl.c code. */ @@ -57,14 +57,18 @@ int selinux_compat_net = SELINUX_COMPAT_NET_VALUE; static int __init checkreqprot_setup(char *str) { - selinux_checkreqprot = simple_strtoul(str, NULL, 0) ? 1 : 0; + unsigned long checkreqprot; + if (!strict_strtoul(str, 0, &checkreqprot)) + selinux_checkreqprot = checkreqprot ? 1 : 0; return 1; } __setup("checkreqprot=", checkreqprot_setup); static int __init selinux_compat_net_setup(char *str) { - selinux_compat_net = simple_strtoul(str, NULL, 0) ? 1 : 0; + unsigned long compat_net; + if (!strict_strtoul(str, 0, &compat_net)) + selinux_compat_net = compat_net ? 1 : 0; return 1; } __setup("selinux_compat_net=", selinux_compat_net_setup); diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 9e6626362bf..a1be97f8bee 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -311,7 +311,7 @@ void avtab_hash_eval(struct avtab *h, char *tag) } printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " - "longest chain length %d sum of chain length^2 %Lu\n", + "longest chain length %d sum of chain length^2 %llu\n", tag, h->nel, slots_used, h->nslot, max_chain_len, chain2_len_sum); } diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index a6ca0587e63..77d745da48b 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -437,13 +437,13 @@ int mls_setup_user_range(struct context *fromcon, struct user_datum *user, struct mls_level *usercon_clr = &(usercon->range.level[1]); /* Honor the user's default level if we can */ - if (mls_level_between(user_def, fromcon_sen, fromcon_clr)) { + if (mls_level_between(user_def, fromcon_sen, fromcon_clr)) *usercon_sen = *user_def; - } else if (mls_level_between(fromcon_sen, user_def, user_clr)) { + else if (mls_level_between(fromcon_sen, user_def, user_clr)) *usercon_sen = *fromcon_sen; - } else if (mls_level_between(fromcon_clr, user_low, user_def)) { + else if (mls_level_between(fromcon_clr, user_low, user_def)) *usercon_sen = *user_low; - } else + else return -EINVAL; /* Lower the clearance of available contexts diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2d5e5a3a8aa..0696aadcab6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2531,7 +2531,7 @@ int selinux_audit_rule_known(struct audit_krule *rule) } int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, - struct audit_context *actx) + struct audit_context *actx) { struct context *ctxt; struct mls_level *level; @@ -2645,7 +2645,7 @@ out: static int (*aurule_callback)(void) = audit_update_lsm_rules; static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, - u16 class, u32 perms, u32 *retained) + u16 class, u32 perms, u32 *retained) { int err = 0; -- GitLab From fdeb05184b8b2500e120647778d63fddba76dc59 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Sun, 18 May 2008 12:32:57 +0100 Subject: [PATCH 1708/2509] SELinux: reorder inode_security_struct to increase objs/slab on 64bit reorder inode_security_struct to remove padding on 64 bit builds size reduced from 72 to 64 bytes increasing objects per slab to 64. Signed-off-by: Richard Kennedy Signed-off-by: James Morris --- security/selinux/include/objsec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 032c2357dad..5f0be19ca43 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -43,8 +43,8 @@ struct inode_security_struct { u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ unsigned char initialized; /* initialization flag */ - struct mutex lock; unsigned char inherit; /* inherit SID from parent entry */ + struct mutex lock; }; struct file_security_struct { -- GitLab From feb2a5b82d87fbdc01c00b7e9413e4b5f4c1f0c1 Mon Sep 17 00:00:00 2001 From: James Morris Date: Tue, 20 May 2008 09:42:33 +1000 Subject: [PATCH 1709/2509] SELinux: remove inherit field from inode_security_struct Remove inherit field from inode_security_struct, per Stephen Smalley: "Let's just drop inherit altogether - dead field." Signed-off-by: James Morris --- security/selinux/include/objsec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 5f0be19ca43..91070ab874c 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -43,7 +43,6 @@ struct inode_security_struct { u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ unsigned char initialized; /* initialization flag */ - unsigned char inherit; /* inherit SID from parent entry */ struct mutex lock; }; -- GitLab From 006ebb40d3d65338bd74abb03b945f8d60e362bd Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 19 May 2008 08:32:49 -0400 Subject: [PATCH 1710/2509] Security: split proc ptrace checking into read vs. attach Enable security modules to distinguish reading of process state via proc from full ptrace access by renaming ptrace_may_attach to ptrace_may_access and adding a mode argument indicating whether only read access or full attach access is requested. This allows security modules to permit access to reading process state without granting full ptrace access. The base DAC/capability checking remains unchanged. Read access to /proc/pid/mem continues to apply a full ptrace attach check since check_mem_permission() already requires the current task to already be ptracing the target. The other ptrace checks within proc for elements like environ, maps, and fds are changed to pass the read mode instead of attach. In the SELinux case, we model such reading of process state as a reading of a proc file labeled with the target process' label. This enables SELinux policy to permit such reading of process state without permitting control or manipulation of the target process, as there are a number of cases where programs probe for such information via proc but do not need to be able to control the target (e.g. procps, lsof, PolicyKit, ConsoleKit). At present we have to choose between allowing full ptrace in policy (more permissive than required/desired) or breaking functionality (or in some cases just silencing the denials via dontaudit rules but this can hide genuine attacks). This version of the patch incorporates comments from Casey Schaufler (change/replace existing ptrace_may_attach interface, pass access mode), and Chris Wright (provide greater consistency in the checking). Note that like their predecessors __ptrace_may_attach and ptrace_may_attach, the __ptrace_may_access and ptrace_may_access interfaces use different return value conventions from each other (0 or -errno vs. 1 or 0). I retained this difference to avoid any changes to the caller logic but made the difference clearer by changing the latter interface to return a bool rather than an int and by adding a comment about it to ptrace.h for any future callers. Signed-off-by: Stephen Smalley Acked-by: Chris Wright Signed-off-by: James Morris --- fs/proc/base.c | 9 +++++---- fs/proc/task_mmu.c | 6 +++--- fs/proc/task_nommu.c | 2 +- include/linux/ptrace.h | 8 ++++++-- include/linux/security.h | 16 +++++++++++----- kernel/ptrace.c | 15 ++++++++------- security/commoncap.c | 3 ++- security/dummy.c | 3 ++- security/security.c | 5 +++-- security/selinux/hooks.c | 13 +++++++++++-- security/smack/smack_lsm.c | 5 +++-- 11 files changed, 55 insertions(+), 30 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 3b455371e7f..58c3e6a8e15 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -233,7 +233,7 @@ static int check_mem_permission(struct task_struct *task) */ if (task->parent == current && (task->ptrace & PT_PTRACED) && task_is_stopped_or_traced(task) && - ptrace_may_attach(task)) + ptrace_may_access(task, PTRACE_MODE_ATTACH)) return 0; /* @@ -251,7 +251,8 @@ struct mm_struct *mm_for_maps(struct task_struct *task) task_lock(task); if (task->mm != mm) goto out; - if (task->mm != current->mm && __ptrace_may_attach(task) < 0) + if (task->mm != current->mm && + __ptrace_may_access(task, PTRACE_MODE_READ) < 0) goto out; task_unlock(task); return mm; @@ -518,7 +519,7 @@ static int proc_fd_access_allowed(struct inode *inode) */ task = get_proc_task(inode); if (task) { - allowed = ptrace_may_attach(task); + allowed = ptrace_may_access(task, PTRACE_MODE_READ); put_task_struct(task); } return allowed; @@ -904,7 +905,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, if (!task) goto out_no_task; - if (!ptrace_may_attach(task)) + if (!ptrace_may_access(task, PTRACE_MODE_READ)) goto out; ret = -ENOMEM; diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c492449f3b4..164bd9f9ede 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -210,7 +210,7 @@ static int show_map(struct seq_file *m, void *v) dev_t dev = 0; int len; - if (maps_protect && !ptrace_may_attach(task)) + if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ)) return -EACCES; if (file) { @@ -646,7 +646,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, goto out; ret = -EACCES; - if (!ptrace_may_attach(task)) + if (!ptrace_may_access(task, PTRACE_MODE_READ)) goto out_task; ret = -EINVAL; @@ -747,7 +747,7 @@ static int show_numa_map_checked(struct seq_file *m, void *v) struct proc_maps_private *priv = m->private; struct task_struct *task = priv->task; - if (maps_protect && !ptrace_may_attach(task)) + if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ)) return -EACCES; return show_numa_map(m, v); diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 4b4f9cc2f18..5d84e7121df 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -113,7 +113,7 @@ static int show_map(struct seq_file *m, void *_vml) struct proc_maps_private *priv = m->private; struct task_struct *task = priv->task; - if (maps_protect && !ptrace_may_attach(task)) + if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ)) return -EACCES; return nommu_vma_show(m, vml->vma); diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index f98501ba557..c6f5f9dd0ce 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -95,8 +95,12 @@ extern void __ptrace_link(struct task_struct *child, struct task_struct *new_parent); extern void __ptrace_unlink(struct task_struct *child); extern void ptrace_untrace(struct task_struct *child); -extern int ptrace_may_attach(struct task_struct *task); -extern int __ptrace_may_attach(struct task_struct *task); +#define PTRACE_MODE_READ 1 +#define PTRACE_MODE_ATTACH 2 +/* Returns 0 on success, -errno on denial. */ +extern int __ptrace_may_access(struct task_struct *task, unsigned int mode); +/* Returns true on success, false on denial. */ +extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); static inline int ptrace_reparented(struct task_struct *child) { diff --git a/include/linux/security.h b/include/linux/security.h index 50737c70e78..62bd80cb7f8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -46,7 +46,8 @@ struct audit_krule; */ extern int cap_capable(struct task_struct *tsk, int cap); extern int cap_settime(struct timespec *ts, struct timezone *tz); -extern int cap_ptrace(struct task_struct *parent, struct task_struct *child); +extern int cap_ptrace(struct task_struct *parent, struct task_struct *child, + unsigned int mode); extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); @@ -1170,6 +1171,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * attributes would be changed by the execve. * @parent contains the task_struct structure for parent process. * @child contains the task_struct structure for child process. + * @mode contains the PTRACE_MODE flags indicating the form of access. * Return 0 if permission is granted. * @capget: * Get the @effective, @inheritable, and @permitted capability sets for @@ -1295,7 +1297,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) struct security_operations { char name[SECURITY_NAME_MAX + 1]; - int (*ptrace) (struct task_struct *parent, struct task_struct *child); + int (*ptrace) (struct task_struct *parent, struct task_struct *child, + unsigned int mode); int (*capget) (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); @@ -1573,7 +1576,8 @@ extern struct dentry *securityfs_create_dir(const char *name, struct dentry *par extern void securityfs_remove(struct dentry *dentry); /* Security operations */ -int security_ptrace(struct task_struct *parent, struct task_struct *child); +int security_ptrace(struct task_struct *parent, struct task_struct *child, + unsigned int mode); int security_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, @@ -1755,9 +1759,11 @@ static inline int security_init(void) return 0; } -static inline int security_ptrace(struct task_struct *parent, struct task_struct *child) +static inline int security_ptrace(struct task_struct *parent, + struct task_struct *child, + unsigned int mode) { - return cap_ptrace(parent, child); + return cap_ptrace(parent, child, mode); } static inline int security_capget(struct task_struct *target, diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 6c19e94fd0a..e337390fce0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -121,7 +121,7 @@ int ptrace_check_attach(struct task_struct *child, int kill) return ret; } -int __ptrace_may_attach(struct task_struct *task) +int __ptrace_may_access(struct task_struct *task, unsigned int mode) { /* May we inspect the given task? * This check is used both for attaching with ptrace @@ -148,16 +148,16 @@ int __ptrace_may_attach(struct task_struct *task) if (!dumpable && !capable(CAP_SYS_PTRACE)) return -EPERM; - return security_ptrace(current, task); + return security_ptrace(current, task, mode); } -int ptrace_may_attach(struct task_struct *task) +bool ptrace_may_access(struct task_struct *task, unsigned int mode) { int err; task_lock(task); - err = __ptrace_may_attach(task); + err = __ptrace_may_access(task, mode); task_unlock(task); - return !err; + return (!err ? true : false); } int ptrace_attach(struct task_struct *task) @@ -195,7 +195,7 @@ repeat: /* the same process cannot be attached many times */ if (task->ptrace & PT_PTRACED) goto bad; - retval = __ptrace_may_attach(task); + retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); if (retval) goto bad; @@ -494,7 +494,8 @@ int ptrace_traceme(void) */ task_lock(current); if (!(current->ptrace & PT_PTRACED)) { - ret = security_ptrace(current->parent, current); + ret = security_ptrace(current->parent, current, + PTRACE_MODE_ATTACH); /* * Set the ptrace bit in the process ptrace flags. */ diff --git a/security/commoncap.c b/security/commoncap.c index 33d34330841..0b6537a3672 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -63,7 +63,8 @@ int cap_settime(struct timespec *ts, struct timezone *tz) return 0; } -int cap_ptrace (struct task_struct *parent, struct task_struct *child) +int cap_ptrace (struct task_struct *parent, struct task_struct *child, + unsigned int mode) { /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */ if (!cap_issubset(child->cap_permitted, parent->cap_permitted) && diff --git a/security/dummy.c b/security/dummy.c index b8916883b77..1db712d99dc 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -30,7 +30,8 @@ #include #include -static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) +static int dummy_ptrace (struct task_struct *parent, struct task_struct *child, + unsigned int mode) { return 0; } diff --git a/security/security.c b/security/security.c index 59838a99b80..c4507ce2a5a 100644 --- a/security/security.c +++ b/security/security.c @@ -161,9 +161,10 @@ int mod_reg_security(const char *name, struct security_operations *ops) /* Security operations */ -int security_ptrace(struct task_struct *parent, struct task_struct *child) +int security_ptrace(struct task_struct *parent, struct task_struct *child, + unsigned int mode) { - return security_ops->ptrace(parent, child); + return security_ops->ptrace(parent, child, mode); } int security_capget(struct task_struct *target, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index eca70f42e67..4be156334b2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1686,14 +1686,23 @@ static inline u32 file_to_av(struct file *file) /* Hook functions begin here. */ -static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) +static int selinux_ptrace(struct task_struct *parent, + struct task_struct *child, + unsigned int mode) { int rc; - rc = secondary_ops->ptrace(parent, child); + rc = secondary_ops->ptrace(parent, child, mode); if (rc) return rc; + if (mode == PTRACE_MODE_READ) { + struct task_security_struct *tsec = parent->security; + struct task_security_struct *csec = child->security; + return avc_has_perm(tsec->sid, csec->sid, + SECCLASS_FILE, FILE__READ, NULL); + } + return task_has_perm(parent, child, PROCESS__PTRACE); } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 4a09293efa0..3c7150b3493 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -95,11 +95,12 @@ struct inode_smack *new_inode_smack(char *smack) * * Do the capability checks, and require read and write. */ -static int smack_ptrace(struct task_struct *ptp, struct task_struct *ctp) +static int smack_ptrace(struct task_struct *ptp, struct task_struct *ctp, + unsigned int mode) { int rc; - rc = cap_ptrace(ptp, ctp); + rc = cap_ptrace(ptp, ctp, mode); if (rc != 0) return rc; -- GitLab From abc69bb633931bf54c6db798bcdc6fd1e0284742 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Wed, 21 May 2008 14:16:12 -0400 Subject: [PATCH 1711/2509] SELinux: enable processes with mac_admin to get the raw inode contexts Enable processes with CAP_MAC_ADMIN + mac_admin permission in policy to get undefined contexts on inodes. This extends the support for deferred mapping of security contexts in order to permit restorecon and similar programs to see the raw file contexts unknown to the system policy in order to check them. Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4be156334b2..91b666aec45 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2754,9 +2754,7 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name) } /* - * Copy the in-core inode security context value to the user. If the - * getxattr() prior to this succeeded, check to see if we need to - * canonicalize the value to be finally returned to the user. + * Copy the inode security context value to the user. * * Permission check is handled by selinux_inode_getxattr hook. */ @@ -2765,12 +2763,33 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name u32 size; int error; char *context = NULL; + struct task_security_struct *tsec = current->security; struct inode_security_struct *isec = inode->i_security; if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP; - error = security_sid_to_context(isec->sid, &context, &size); + /* + * If the caller has CAP_MAC_ADMIN, then get the raw context + * value even if it is not defined by current policy; otherwise, + * use the in-core value under current policy. + * Use the non-auditing forms of the permission checks since + * getxattr may be called by unprivileged processes commonly + * and lack of permission just means that we fall back to the + * in-core context value, not a denial. + */ + error = secondary_ops->capable(current, CAP_MAC_ADMIN); + if (!error) + error = avc_has_perm_noaudit(tsec->sid, tsec->sid, + SECCLASS_CAPABILITY2, + CAPABILITY2__MAC_ADMIN, + 0, + NULL); + if (!error) + error = security_sid_to_context_force(isec->sid, &context, + &size); + else + error = security_sid_to_context(isec->sid, &context, &size); if (error) return error; error = size; -- GitLab From 242631c49d4cf39642741d6627750151b058233b Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 5 Jun 2008 09:21:28 -0400 Subject: [PATCH 1712/2509] selinux: simplify ioctl checking Simplify and improve the robustness of the SELinux ioctl checking by using the "access mode" bits of the ioctl command to determine the permission check rather than dealing with individual command values. This removes any knowledge of specific ioctl commands from SELinux and follows the same guidance we gave to Smack earlier. Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 48 +++++++--------------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 91b666aec45..f53000803a5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -42,9 +42,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -2903,46 +2901,16 @@ static void selinux_file_free_security(struct file *file) static int selinux_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int error = 0; - - switch (cmd) { - case FIONREAD: - /* fall through */ - case FIBMAP: - /* fall through */ - case FIGETBSZ: - /* fall through */ - case EXT2_IOC_GETFLAGS: - /* fall through */ - case EXT2_IOC_GETVERSION: - error = file_has_perm(current, file, FILE__GETATTR); - break; - - case EXT2_IOC_SETFLAGS: - /* fall through */ - case EXT2_IOC_SETVERSION: - error = file_has_perm(current, file, FILE__SETATTR); - break; - - /* sys_ioctl() checks */ - case FIONBIO: - /* fall through */ - case FIOASYNC: - error = file_has_perm(current, file, 0); - break; + u32 av = 0; - case KDSKBENT: - case KDSKBSENT: - error = task_has_capability(current, CAP_SYS_TTY_CONFIG); - break; + if (_IOC_DIR(cmd) & _IOC_WRITE) + av |= FILE__WRITE; + if (_IOC_DIR(cmd) & _IOC_READ) + av |= FILE__READ; + if (!av) + av = FILE__IOCTL; - /* default case assumes that the command will go - * to the file's ioctl() function. - */ - default: - error = file_has_perm(current, file, FILE__IOCTL); - } - return error; + return file_has_perm(current, file, av); } static int file_map_prot_check(struct file *file, unsigned long prot, int shared) -- GitLab From 59dbd1ba9847837aa7095f3e4a29599dae412ac4 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 5 Jun 2008 09:48:51 -0400 Subject: [PATCH 1713/2509] selinux: fix endianness bug in network node address handling Fix an endianness bug in the handling of network node addresses by SELinux. This yields no change on little endian hardware but fixes the incorrect handling on big endian hardware. The network node addresses are stored in network order in memory by checkpolicy, not in cpu/host order, and thus should not have cpu_to_le32/le32_to_cpu conversions applied upon policy write/read unlike other data in the policy. Bug reported by John Weeks of Sun, who noticed that binary policy files built from the same policy source on x86 and sparc differed and tracked it down to the ipv4 address handling in checkpolicy. Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/ss/policydb.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 84f8cc73c7d..2391761ae42 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1478,7 +1478,8 @@ int policydb_read(struct policydb *p, void *fp) struct ocontext *l, *c, *newc; struct genfs *genfs_p, *genfs, *newgenfs; int i, j, rc; - __le32 buf[8]; + __le32 buf[4]; + u32 nodebuf[8]; u32 len, len2, config, nprim, nel, nel2; char *policydb_str; struct policydb_compat_info *info; @@ -1749,11 +1750,11 @@ int policydb_read(struct policydb *p, void *fp) goto bad; break; case OCON_NODE: - rc = next_entry(buf, fp, sizeof(u32) * 2); + rc = next_entry(nodebuf, fp, sizeof(u32) * 2); if (rc < 0) goto bad; - c->u.node.addr = le32_to_cpu(buf[0]); - c->u.node.mask = le32_to_cpu(buf[1]); + c->u.node.addr = nodebuf[0]; /* network order */ + c->u.node.mask = nodebuf[1]; /* network order */ rc = context_read_and_validate(&c->context[0], p, fp); if (rc) goto bad; @@ -1782,13 +1783,13 @@ int policydb_read(struct policydb *p, void *fp) case OCON_NODE6: { int k; - rc = next_entry(buf, fp, sizeof(u32) * 8); + rc = next_entry(nodebuf, fp, sizeof(u32) * 8); if (rc < 0) goto bad; for (k = 0; k < 4; k++) - c->u.node6.addr[k] = le32_to_cpu(buf[k]); + c->u.node6.addr[k] = nodebuf[k]; for (k = 0; k < 4; k++) - c->u.node6.mask[k] = le32_to_cpu(buf[k+4]); + c->u.node6.mask[k] = nodebuf[k+4]; if (context_read_and_validate(&c->context[0], p, fp)) goto bad; break; -- GitLab From 0804d1133c02cbdfba0055de774f2c21a8b777dc Mon Sep 17 00:00:00 2001 From: James Morris Date: Fri, 6 Jun 2008 18:40:29 +1000 Subject: [PATCH 1714/2509] SELinux: open code policy_rwlock Open code policy_rwlock, as suggested by Andrew Morton. Signed-off-by: James Morris Acked-by: Stephen Smalley --- security/selinux/ss/services.c | 108 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 0696aadcab6..e8ec54db95b 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -71,10 +71,6 @@ int selinux_policycap_openperm; extern const struct selinux_class_perm selinux_class_perm; static DEFINE_RWLOCK(policy_rwlock); -#define POLICY_RDLOCK read_lock(&policy_rwlock) -#define POLICY_WRLOCK write_lock_irq(&policy_rwlock) -#define POLICY_RDUNLOCK read_unlock(&policy_rwlock) -#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock) static DEFINE_MUTEX(load_mutex); #define LOAD_LOCK mutex_lock(&load_mutex) @@ -429,7 +425,7 @@ int security_permissive_sid(u32 sid) u32 type; int rc; - POLICY_RDLOCK; + read_lock(&policy_rwlock); context = sidtab_search(&sidtab, sid); BUG_ON(!context); @@ -441,7 +437,7 @@ int security_permissive_sid(u32 sid) */ rc = ebitmap_get_bit(&policydb.permissive_map, type); - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -486,7 +482,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, if (!ss_initialized) return 0; - POLICY_RDLOCK; + read_lock(&policy_rwlock); /* * Remap extended Netlink classes for old policy versions. @@ -543,7 +539,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -578,7 +574,7 @@ int security_compute_av(u32 ssid, return 0; } - POLICY_RDLOCK; + read_lock(&policy_rwlock); scontext = sidtab_search(&sidtab, ssid); if (!scontext) { @@ -598,7 +594,7 @@ int security_compute_av(u32 ssid, rc = context_struct_compute_av(scontext, tcontext, tclass, requested, avd); out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -691,7 +687,7 @@ static int security_sid_to_context_core(u32 sid, char **scontext, rc = -EINVAL; goto out; } - POLICY_RDLOCK; + read_lock(&policy_rwlock); if (force) context = sidtab_search_force(&sidtab, sid); else @@ -704,7 +700,7 @@ static int security_sid_to_context_core(u32 sid, char **scontext, } rc = context_struct_to_string(context, scontext, scontext_len); out_unlock: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); out: return rc; @@ -855,7 +851,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, } } - POLICY_RDLOCK; + read_lock(&policy_rwlock); rc = string_to_context_struct(&policydb, &sidtab, scontext2, scontext_len, &context, def_sid); @@ -869,7 +865,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, if (rc) context_destroy(&context); out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); kfree(scontext2); kfree(str); return rc; @@ -981,7 +977,7 @@ static int security_compute_sid(u32 ssid, context_init(&newcontext); - POLICY_RDLOCK; + read_lock(&policy_rwlock); scontext = sidtab_search(&sidtab, ssid); if (!scontext) { @@ -1086,7 +1082,7 @@ static int security_compute_sid(u32 ssid, /* Obtain the sid for the context. */ rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid); out_unlock: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); context_destroy(&newcontext); out: return rc; @@ -1549,13 +1545,13 @@ int security_load_policy(void *data, size_t len) sidtab_set(&oldsidtab, &sidtab); /* Install the new policydb and SID table. */ - POLICY_WRLOCK; + write_lock_irq(&policy_rwlock); memcpy(&policydb, &newpolicydb, sizeof policydb); sidtab_set(&sidtab, &newsidtab); security_load_policycaps(); seqno = ++latest_granting; policydb_loaded_version = policydb.policyvers; - POLICY_WRUNLOCK; + write_unlock_irq(&policy_rwlock); LOAD_UNLOCK; /* Free the old policydb and SID table. */ @@ -1588,7 +1584,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid) struct ocontext *c; int rc = 0; - POLICY_RDLOCK; + read_lock(&policy_rwlock); c = policydb.ocontexts[OCON_PORT]; while (c) { @@ -1613,7 +1609,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid) } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -1627,7 +1623,7 @@ int security_netif_sid(char *name, u32 *if_sid) int rc = 0; struct ocontext *c; - POLICY_RDLOCK; + read_lock(&policy_rwlock); c = policydb.ocontexts[OCON_NETIF]; while (c) { @@ -1654,7 +1650,7 @@ int security_netif_sid(char *name, u32 *if_sid) *if_sid = SECINITSID_NETIF; out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -1686,7 +1682,7 @@ int security_node_sid(u16 domain, int rc = 0; struct ocontext *c; - POLICY_RDLOCK; + read_lock(&policy_rwlock); switch (domain) { case AF_INET: { @@ -1741,7 +1737,7 @@ int security_node_sid(u16 domain, } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -1780,7 +1776,7 @@ int security_get_user_sids(u32 fromsid, if (!ss_initialized) goto out; - POLICY_RDLOCK; + read_lock(&policy_rwlock); context_init(&usercon); @@ -1833,7 +1829,7 @@ int security_get_user_sids(u32 fromsid, } out_unlock: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); if (rc || !mynel) { kfree(mysids); goto out; @@ -1886,7 +1882,7 @@ int security_genfs_sid(const char *fstype, while (path[0] == '/' && path[1] == '/') path++; - POLICY_RDLOCK; + read_lock(&policy_rwlock); for (genfs = policydb.genfs; genfs; genfs = genfs->next) { cmp = strcmp(fstype, genfs->fstype); @@ -1923,7 +1919,7 @@ int security_genfs_sid(const char *fstype, *sid = c->sid[0]; out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -1941,7 +1937,7 @@ int security_fs_use( int rc = 0; struct ocontext *c; - POLICY_RDLOCK; + read_lock(&policy_rwlock); c = policydb.ocontexts[OCON_FSUSE]; while (c) { @@ -1971,7 +1967,7 @@ int security_fs_use( } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -1979,7 +1975,7 @@ int security_get_bools(int *len, char ***names, int **values) { int i, rc = -ENOMEM; - POLICY_RDLOCK; + read_lock(&policy_rwlock); *names = NULL; *values = NULL; @@ -2009,7 +2005,7 @@ int security_get_bools(int *len, char ***names, int **values) } rc = 0; out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; err: if (*names) { @@ -2027,7 +2023,7 @@ int security_set_bools(int len, int *values) int lenp, seqno = 0; struct cond_node *cur; - POLICY_WRLOCK; + write_lock_irq(&policy_rwlock); lenp = policydb.p_bools.nprim; if (len != lenp) { @@ -2061,7 +2057,7 @@ int security_set_bools(int len, int *values) seqno = ++latest_granting; out: - POLICY_WRUNLOCK; + write_unlock_irq(&policy_rwlock); if (!rc) { avc_ss_reset(seqno); selnl_notify_policyload(seqno); @@ -2075,7 +2071,7 @@ int security_get_bool_value(int bool) int rc = 0; int len; - POLICY_RDLOCK; + read_lock(&policy_rwlock); len = policydb.p_bools.nprim; if (bool >= len) { @@ -2085,7 +2081,7 @@ int security_get_bool_value(int bool) rc = policydb.bool_val_to_struct[bool]->state; out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -2140,7 +2136,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) context_init(&newcon); - POLICY_RDLOCK; + read_lock(&policy_rwlock); context1 = sidtab_search(&sidtab, sid); if (!context1) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", @@ -2182,7 +2178,7 @@ bad: } out_unlock: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); context_destroy(&newcon); out: return rc; @@ -2239,7 +2235,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, return 0; } - POLICY_RDLOCK; + read_lock(&policy_rwlock); nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); if (!nlbl_ctx) { @@ -2258,7 +2254,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); out_slowpath: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); if (rc == 0) /* at present NetLabel SIDs/labels really only carry MLS * information so if the MLS portion of the NetLabel SID @@ -2288,7 +2284,7 @@ int security_get_classes(char ***classes, int *nclasses) { int rc = -ENOMEM; - POLICY_RDLOCK; + read_lock(&policy_rwlock); *nclasses = policydb.p_classes.nprim; *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); @@ -2305,7 +2301,7 @@ int security_get_classes(char ***classes, int *nclasses) } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -2327,7 +2323,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms) int rc = -ENOMEM, i; struct class_datum *match; - POLICY_RDLOCK; + read_lock(&policy_rwlock); match = hashtab_search(policydb.p_classes.table, class); if (!match) { @@ -2355,11 +2351,11 @@ int security_get_permissions(char *class, char ***perms, int *nperms) goto err; out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; err: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); for (i = 0; i < *nperms; i++) kfree((*perms)[i]); kfree(*perms); @@ -2390,9 +2386,9 @@ int security_policycap_supported(unsigned int req_cap) { int rc; - POLICY_RDLOCK; + read_lock(&policy_rwlock); rc = ebitmap_get_bit(&policydb.policycaps, req_cap); - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } @@ -2456,7 +2452,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) context_init(&tmprule->au_ctxt); - POLICY_RDLOCK; + read_lock(&policy_rwlock); tmprule->au_seqno = latest_granting; @@ -2493,7 +2489,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) break; } - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); if (rc) { selinux_audit_rule_free(tmprule); @@ -2544,7 +2540,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, return -ENOENT; } - POLICY_RDLOCK; + read_lock(&policy_rwlock); if (rule->au_seqno < latest_granting) { audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, @@ -2638,7 +2634,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, } out: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return match; } @@ -2726,7 +2722,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, return 0; } - POLICY_RDLOCK; + read_lock(&policy_rwlock); if (secattr->flags & NETLBL_SECATTR_CACHE) { *sid = *(u32 *)secattr->cache->data; @@ -2771,7 +2767,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, } netlbl_secattr_to_sid_return: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; netlbl_secattr_to_sid_return_cleanup: ebitmap_destroy(&ctx_new.range.level[0].cat); @@ -2796,7 +2792,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) if (!ss_initialized) return 0; - POLICY_RDLOCK; + read_lock(&policy_rwlock); ctx = sidtab_search(&sidtab, sid); if (ctx == NULL) goto netlbl_sid_to_secattr_failure; @@ -2807,12 +2803,12 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) rc = mls_export_netlbl_cat(ctx, secattr); if (rc != 0) goto netlbl_sid_to_secattr_failure; - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return 0; netlbl_sid_to_secattr_failure: - POLICY_RDUNLOCK; + read_unlock(&policy_rwlock); return rc; } #endif /* CONFIG_NETLABEL */ -- GitLab From 972ccac2b237967ed7e56a50eb181b5a0a484b79 Mon Sep 17 00:00:00 2001 From: James Morris Date: Fri, 6 Jun 2008 18:43:26 +1000 Subject: [PATCH 1715/2509] SELinux: open code load_mutex Open code load_mutex as suggested by Andrew Morton. Signed-off-by: James Morris --- security/selinux/ss/services.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e8ec54db95b..d06df335ee7 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -71,10 +71,7 @@ int selinux_policycap_openperm; extern const struct selinux_class_perm selinux_class_perm; static DEFINE_RWLOCK(policy_rwlock); - static DEFINE_MUTEX(load_mutex); -#define LOAD_LOCK mutex_lock(&load_mutex) -#define LOAD_UNLOCK mutex_unlock(&load_mutex) static struct sidtab sidtab; struct policydb policydb; @@ -1456,17 +1453,17 @@ int security_load_policy(void *data, size_t len) int rc = 0; struct policy_file file = { data, len }, *fp = &file; - LOAD_LOCK; + mutex_lock(&load_mutex); if (!ss_initialized) { avtab_cache_init(); if (policydb_read(&policydb, fp)) { - LOAD_UNLOCK; + mutex_unlock(&load_mutex); avtab_cache_destroy(); return -EINVAL; } if (policydb_load_isids(&policydb, &sidtab)) { - LOAD_UNLOCK; + mutex_unlock(&load_mutex); policydb_destroy(&policydb); avtab_cache_destroy(); return -EINVAL; @@ -1475,7 +1472,7 @@ int security_load_policy(void *data, size_t len) if (validate_classes(&policydb)) { printk(KERN_ERR "SELinux: the definition of a class is incorrect\n"); - LOAD_UNLOCK; + mutex_unlock(&load_mutex); sidtab_destroy(&sidtab); policydb_destroy(&policydb); avtab_cache_destroy(); @@ -1485,7 +1482,7 @@ int security_load_policy(void *data, size_t len) policydb_loaded_version = policydb.policyvers; ss_initialized = 1; seqno = ++latest_granting; - LOAD_UNLOCK; + mutex_unlock(&load_mutex); selinux_complete_init(); avc_ss_reset(seqno); selnl_notify_policyload(seqno); @@ -1499,12 +1496,12 @@ int security_load_policy(void *data, size_t len) #endif if (policydb_read(&newpolicydb, fp)) { - LOAD_UNLOCK; + mutex_unlock(&load_mutex); return -EINVAL; } if (sidtab_init(&newsidtab)) { - LOAD_UNLOCK; + mutex_unlock(&load_mutex); policydb_destroy(&newpolicydb); return -ENOMEM; } @@ -1552,7 +1549,7 @@ int security_load_policy(void *data, size_t len) seqno = ++latest_granting; policydb_loaded_version = policydb.policyvers; write_unlock_irq(&policy_rwlock); - LOAD_UNLOCK; + mutex_unlock(&load_mutex); /* Free the old policydb and SID table. */ policydb_destroy(&oldpolicydb); @@ -1566,7 +1563,7 @@ int security_load_policy(void *data, size_t len) return 0; err: - LOAD_UNLOCK; + mutex_unlock(&load_mutex); sidtab_destroy(&newsidtab); policydb_destroy(&newpolicydb); return rc; -- GitLab From bdd581c1439339f1d3e8446b83e0f1beaef294e9 Mon Sep 17 00:00:00 2001 From: James Morris Date: Fri, 6 Jun 2008 18:50:12 +1000 Subject: [PATCH 1716/2509] SELinux: open code sidtab lock Open code sidtab lock to make Andrew Morton happy. Signed-off-by: James Morris Acked-by: Stephen Smalley --- security/selinux/ss/sidtab.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index ba354164049..a81ded10412 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -14,10 +14,6 @@ #define SIDTAB_HASH(sid) \ (sid & SIDTAB_HASH_MASK) -#define INIT_SIDTAB_LOCK(s) spin_lock_init(&s->lock) -#define SIDTAB_LOCK(s, x) spin_lock_irqsave(&s->lock, x) -#define SIDTAB_UNLOCK(s, x) spin_unlock_irqrestore(&s->lock, x) - int sidtab_init(struct sidtab *s) { int i; @@ -30,7 +26,7 @@ int sidtab_init(struct sidtab *s) s->nel = 0; s->next_sid = 1; s->shutdown = 0; - INIT_SIDTAB_LOCK(s); + spin_lock_init(&s->lock); return 0; } @@ -180,7 +176,7 @@ int sidtab_context_to_sid(struct sidtab *s, sid = sidtab_search_context(s, context); if (!sid) { - SIDTAB_LOCK(s, flags); + spin_lock_irqsave(&s->lock, flags); /* Rescan now that we hold the lock. */ sid = sidtab_search_context(s, context); if (sid) @@ -199,7 +195,7 @@ int sidtab_context_to_sid(struct sidtab *s, if (ret) s->next_sid--; unlock_out: - SIDTAB_UNLOCK(s, flags); + spin_unlock_irqrestore(&s->lock, flags); } if (ret) @@ -264,19 +260,19 @@ void sidtab_set(struct sidtab *dst, struct sidtab *src) { unsigned long flags; - SIDTAB_LOCK(src, flags); + spin_lock_irqsave(&src->lock, flags); dst->htable = src->htable; dst->nel = src->nel; dst->next_sid = src->next_sid; dst->shutdown = 0; - SIDTAB_UNLOCK(src, flags); + spin_unlock_irqrestore(&src->lock, flags); } void sidtab_shutdown(struct sidtab *s) { unsigned long flags; - SIDTAB_LOCK(s, flags); + spin_lock_irqsave(&s->lock, flags); s->shutdown = 1; - SIDTAB_UNLOCK(s, flags); + spin_unlock_irqrestore(&s->lock, flags); } -- GitLab From cea78dc4ca044e9666e8f5d797ec50ab85253e49 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 9 Jun 2008 15:43:12 -0400 Subject: [PATCH 1717/2509] SELinux: fix off by 1 reference of class_to_string in context_struct_compute_av The class_to_string array is referenced by tclass. My code mistakenly was using tclass - 1. If the proceeding class is a userspace class rather than kernel class this may cause a denial/EINVAL even if unknown handling is set to allow. The bug shouldn't be allowing excess privileges since those are given based on the contents of another array which should be correctly referenced. At this point in time its pretty unlikely this is going to cause problems. The most recently added kernel classes which could be affected are association, dccp_socket, and peer. Its pretty unlikely any policy with handle_unknown=allow doesn't have association and dccp_socket undefined (they've been around longer than unknown handling) and peer is conditionalized on a policy cap which should only be defined if that class exists in policy. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/ss/services.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d06df335ee7..f26a8cad06e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -325,7 +325,7 @@ static int context_struct_compute_av(struct context *scontext, goto inval_class; if (unlikely(tclass > policydb.p_classes.nprim)) if (tclass > kdefs->cts_len || - !kdefs->class_to_string[tclass - 1] || + !kdefs->class_to_string[tclass] || !policydb.allow_unknown) goto inval_class; -- GitLab From 89abd0acf0335f3f760a3c0698d43bb1eaa83e44 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 9 Jun 2008 15:58:04 -0400 Subject: [PATCH 1718/2509] SELinux: drop load_mutex in security_load_policy We used to protect against races of policy load in security_load_policy by using the load_mutex. Since then we have added a new mutex, sel_mutex, in sel_write_load() which is always held across all calls to security_load_policy we are covered and can safely just drop this one. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/ss/services.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index f26a8cad06e..543fd0f31b3 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -71,7 +71,6 @@ int selinux_policycap_openperm; extern const struct selinux_class_perm selinux_class_perm; static DEFINE_RWLOCK(policy_rwlock); -static DEFINE_MUTEX(load_mutex); static struct sidtab sidtab; struct policydb policydb; @@ -1453,17 +1452,13 @@ int security_load_policy(void *data, size_t len) int rc = 0; struct policy_file file = { data, len }, *fp = &file; - mutex_lock(&load_mutex); - if (!ss_initialized) { avtab_cache_init(); if (policydb_read(&policydb, fp)) { - mutex_unlock(&load_mutex); avtab_cache_destroy(); return -EINVAL; } if (policydb_load_isids(&policydb, &sidtab)) { - mutex_unlock(&load_mutex); policydb_destroy(&policydb); avtab_cache_destroy(); return -EINVAL; @@ -1472,7 +1467,6 @@ int security_load_policy(void *data, size_t len) if (validate_classes(&policydb)) { printk(KERN_ERR "SELinux: the definition of a class is incorrect\n"); - mutex_unlock(&load_mutex); sidtab_destroy(&sidtab); policydb_destroy(&policydb); avtab_cache_destroy(); @@ -1482,7 +1476,6 @@ int security_load_policy(void *data, size_t len) policydb_loaded_version = policydb.policyvers; ss_initialized = 1; seqno = ++latest_granting; - mutex_unlock(&load_mutex); selinux_complete_init(); avc_ss_reset(seqno); selnl_notify_policyload(seqno); @@ -1495,13 +1488,10 @@ int security_load_policy(void *data, size_t len) sidtab_hash_eval(&sidtab, "sids"); #endif - if (policydb_read(&newpolicydb, fp)) { - mutex_unlock(&load_mutex); + if (policydb_read(&newpolicydb, fp)) return -EINVAL; - } if (sidtab_init(&newsidtab)) { - mutex_unlock(&load_mutex); policydb_destroy(&newpolicydb); return -ENOMEM; } @@ -1549,7 +1539,6 @@ int security_load_policy(void *data, size_t len) seqno = ++latest_granting; policydb_loaded_version = policydb.policyvers; write_unlock_irq(&policy_rwlock); - mutex_unlock(&load_mutex); /* Free the old policydb and SID table. */ policydb_destroy(&oldpolicydb); @@ -1563,7 +1552,6 @@ int security_load_policy(void *data, size_t len) return 0; err: - mutex_unlock(&load_mutex); sidtab_destroy(&newsidtab); policydb_destroy(&newpolicydb); return rc; -- GitLab From 22df4adb049a5cbb340dd935f5bbfa1ab3947562 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 9 Jun 2008 16:03:56 -0400 Subject: [PATCH 1719/2509] selinux: change handling of invalid classes (Was: Re: 2.6.26-rc5-mm1 selinux whine) On Mon, 2008-06-09 at 01:24 -0700, Andrew Morton wrote: > Getting a few of these with FC5: > > SELinux: context_struct_compute_av: unrecognized class 69 > SELinux: context_struct_compute_av: unrecognized class 69 > > one came out when I logged in. > > No other symptoms, yet. Change handling of invalid classes by SELinux, reporting class values unknown to the kernel as errors (w/ ratelimit applied) and handling class values unknown to policy as normal denials. Signed-off-by: Stephen Smalley Acked-by: Eric Paris Signed-off-by: James Morris --- security/selinux/ss/services.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 543fd0f31b3..04c0b70c801 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -407,9 +407,19 @@ static int context_struct_compute_av(struct context *scontext, return 0; inval_class: - printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", __func__, - tclass); - return -EINVAL; + if (!tclass || tclass > kdefs->cts_len || + !kdefs->class_to_string[tclass]) { + if (printk_ratelimit()) + printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", + __func__, tclass); + return -EINVAL; + } + + /* + * Known to the kernel, but not to the policy. + * Handle as a denial (allowed is 0). + */ + return 0; } /* -- GitLab From 6cbe27061a69ab89d25dbe42d1a4f33a8425fe88 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 9 Jun 2008 16:51:37 -0400 Subject: [PATCH 1720/2509] SELinux: more user friendly unknown handling printk I've gotten complaints and reports about people not understanding the meaning of the current unknown class/perm handling the kernel emits on every policy load. Hopefully this will make make it clear to everyone the meaning of the message and won't waste a printk the user won't care about anyway on systems where the kernel and the policy agree on everything. Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/selinuxfs.c | 5 ----- security/selinux/ss/services.c | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 07a5db69571..69c9dccc8cf 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -356,11 +356,6 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, length = count; out1: - - printk(KERN_INFO "SELinux: policy loaded with handle_unknown=%s\n", - (security_get_reject_unknown() ? "reject" : - (security_get_allow_unknown() ? "allow" : "deny"))); - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, "policy loaded auid=%u ses=%u", audit_get_loginuid(current), diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 04c0b70c801..b52f923ce68 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1171,6 +1171,7 @@ static int validate_classes(struct policydb *p) const struct selinux_class_perm *kdefs = &selinux_class_perm; const char *def_class, *def_perm, *pol_class; struct symtab *perms; + bool print_unknown_handle = 0; if (p->allow_unknown) { u32 num_classes = kdefs->cts_len; @@ -1191,6 +1192,7 @@ static int validate_classes(struct policydb *p) return -EINVAL; if (p->allow_unknown) p->undefined_perms[i-1] = ~0U; + print_unknown_handle = 1; continue; } pol_class = p->p_class_val_to_name[i-1]; @@ -1220,6 +1222,7 @@ static int validate_classes(struct policydb *p) return -EINVAL; if (p->allow_unknown) p->undefined_perms[class_val-1] |= perm_val; + print_unknown_handle = 1; continue; } perdatum = hashtab_search(perms->table, def_perm); @@ -1267,6 +1270,7 @@ static int validate_classes(struct policydb *p) return -EINVAL; if (p->allow_unknown) p->undefined_perms[class_val-1] |= (1 << j); + print_unknown_handle = 1; continue; } perdatum = hashtab_search(perms->table, def_perm); @@ -1284,6 +1288,9 @@ static int validate_classes(struct policydb *p) } } } + if (print_unknown_handle) + printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n", + (security_get_allow_unknown() ? "allowed" : "denied")); return 0; } -- GitLab From e399f98224a03d2e85fb45eacba367c47173f6f9 Mon Sep 17 00:00:00 2001 From: James Morris Date: Thu, 12 Jun 2008 01:39:58 +1000 Subject: [PATCH 1721/2509] SELinux: remove unused and shadowed addrlen variable Remove unused and shadowed addrlen variable. Picked up by sparse. Signed-off-by: James Morris Acked-by: Stephen Smalley Acked-by: Paul Moore --- security/selinux/hooks.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f53000803a5..6e8d0e91c0c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3669,7 +3669,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in struct sockaddr_in6 *addr6 = NULL; unsigned short snum; struct sock *sk = sock->sk; - u32 sid, node_perm, addrlen; + u32 sid, node_perm; tsec = current->security; isec = SOCK_INODE(sock)->i_security; @@ -3677,12 +3677,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (family == PF_INET) { addr4 = (struct sockaddr_in *)address; snum = ntohs(addr4->sin_port); - addrlen = sizeof(addr4->sin_addr.s_addr); addrp = (char *)&addr4->sin_addr.s_addr; } else { addr6 = (struct sockaddr_in6 *)address; snum = ntohs(addr6->sin6_port); - addrlen = sizeof(addr6->sin6_addr.s6_addr); addrp = (char *)&addr6->sin6_addr.s6_addr; } -- GitLab From 2baf06df85b27c1d64867883a0692519594f1ef2 Mon Sep 17 00:00:00 2001 From: James Morris Date: Thu, 12 Jun 2008 01:42:35 +1000 Subject: [PATCH 1722/2509] SELinux: use do_each_thread as a proper do/while block Use do_each_thread as a proper do/while block. Sparse complained. Signed-off-by: James Morris Acked-by: Stephen Smalley --- security/selinux/hooks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6e8d0e91c0c..4130d64359a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5196,12 +5196,12 @@ static int selinux_setprocattr(struct task_struct *p, struct task_struct *g, *t; struct mm_struct *mm = p->mm; read_lock(&tasklist_lock); - do_each_thread(g, t) + do_each_thread(g, t) { if (t->mm == mm && t != p) { read_unlock(&tasklist_lock); return -EPERM; } - while_each_thread(g, t); + } while_each_thread(g, t); read_unlock(&tasklist_lock); } -- GitLab From 65fc7668006b537f7ae8451990c0ed9ec882544e Mon Sep 17 00:00:00 2001 From: James Morris Date: Thu, 12 Jun 2008 01:00:10 +1000 Subject: [PATCH 1723/2509] security: fix return of void-valued expressions Fix several warnings generated by sparse of the form "returning void-valued expression". Signed-off-by: James Morris Acked-by: Casey Schaufler Acked-by: Serge Hallyn --- security/security.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/security.c b/security/security.c index c4507ce2a5a..2c0a5876b93 100644 --- a/security/security.c +++ b/security/security.c @@ -895,7 +895,7 @@ EXPORT_SYMBOL(security_secctx_to_secid); void security_release_secctx(char *secdata, u32 seclen) { - return security_ops->release_secctx(secdata, seclen); + security_ops->release_secctx(secdata, seclen); } EXPORT_SYMBOL(security_release_secctx); @@ -1012,12 +1012,12 @@ int security_sk_alloc(struct sock *sk, int family, gfp_t priority) void security_sk_free(struct sock *sk) { - return security_ops->sk_free_security(sk); + security_ops->sk_free_security(sk); } void security_sk_clone(const struct sock *sk, struct sock *newsk) { - return security_ops->sk_clone_security(sk, newsk); + security_ops->sk_clone_security(sk, newsk); } void security_sk_classify_flow(struct sock *sk, struct flowi *fl) -- GitLab From 811f3799279e567aa354c649ce22688d949ac7a9 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 18 Jun 2008 09:50:04 -0400 Subject: [PATCH 1724/2509] SELinux: allow fstype unknown to policy to use xattrs if present Currently if a FS is mounted for which SELinux policy does not define an fs_use_* that FS will either be genfs labeled or not labeled at all. This decision is based on the existence of a genfscon rule in policy and is irrespective of the capabilities of the filesystem itself. This patch allows the kernel to check if the filesystem supports security xattrs and if so will use those if there is no fs_use_* rule in policy. An fstype with a no fs_use_* rule but with a genfs rule will use xattrs if available and will follow the genfs rule. This can be particularly interesting for things like ecryptfs which actually overlays a real underlying FS. If we define excryptfs in policy to use xattrs we will likely get this wrong at times, so with this path we just don't need to define it! Overlay ecryptfs on top of NFS with no xattr support: SELinux: initialized (dev ecryptfs, type ecryptfs), uses genfs_contexts Overlay ecryptfs on top of ext4 with xattr support: SELinux: initialized (dev ecryptfs, type ecryptfs), uses xattr It is also useful as the kernel adds new FS we don't need to add them in policy if they support xattrs and that is how we want to handle them. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 22 +++++++++++++++++----- security/selinux/include/security.h | 2 +- security/selinux/ss/services.c | 27 +++++++++++++++++++-------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4130d64359a..85f74f66576 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -556,13 +556,15 @@ 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 inode *inode = sbsec->sb->s_root->d_inode; - struct inode_security_struct *root_isec = inode->i_security; + struct dentry *root = sb->s_root; + struct inode *root_inode = root->d_inode; + struct inode_security_struct *root_isec = root_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); @@ -666,14 +668,24 @@ static int selinux_set_mnt_opts(struct super_block *sb, goto out; } - if (strcmp(sb->s_type->name, "proc") == 0) + if (strcmp(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(sb->s_type->name, &sbsec->behavior, &sbsec->sid); + rc = security_fs_use(name, &sbsec->behavior, &sbsec->sid, can_xattr); if (rc) { printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", - __func__, sb->s_type->name, rc); + __func__, name, rc); goto out; } diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 7c543003d65..44cba2e21dc 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); + u32 *sid, bool can_xattr); 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 b52f923ce68..8e42da12010 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1934,7 +1934,8 @@ out: int security_fs_use( const char *fstype, unsigned int *behavior, - u32 *sid) + u32 *sid, + bool can_xattr) { int rc = 0; struct ocontext *c; @@ -1948,6 +1949,7 @@ int security_fs_use( c = c->next; } + /* look for labeling behavior defined in policy */ if (c) { *behavior = c->v.behavior; if (!c->sid[0]) { @@ -1958,14 +1960,23 @@ 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 { - rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); - if (rc) { - *behavior = SECURITY_FS_USE_NONE; - rc = 0; - } else { - *behavior = SECURITY_FS_USE_GENFS; - } + *behavior = SECURITY_FS_USE_GENFS; } out: -- GitLab From 2069f457848f846cb31149c9aa29b330a6b66d1b Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 4 Jul 2008 09:47:13 +1000 Subject: [PATCH 1725/2509] LSM/SELinux: show LSM mount options in /proc/mounts This patch causes SELinux mount options to show up in /proc/mounts. As with other code in the area seq_put errors are ignored. Other LSM's will not have their mount options displayed until they fill in their own security_sb_show_options() function. Signed-off-by: Eric Paris Signed-off-by: Miklos Szeredi Signed-off-by: James Morris --- fs/namespace.c | 14 +++++++--- include/linux/security.h | 9 +++++++ security/dummy.c | 6 +++++ security/security.c | 5 ++++ security/selinux/hooks.c | 55 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 85 insertions(+), 4 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 4fc302c2a0e..4f6f7635b59 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -750,7 +750,7 @@ struct proc_fs_info { const char *str; }; -static void show_sb_opts(struct seq_file *m, struct super_block *sb) +static int show_sb_opts(struct seq_file *m, struct super_block *sb) { static const struct proc_fs_info fs_info[] = { { MS_SYNCHRONOUS, ",sync" }, @@ -764,6 +764,8 @@ static void show_sb_opts(struct seq_file *m, struct super_block *sb) if (sb->s_flags & fs_infop->flag) seq_puts(m, fs_infop->str); } + + return security_sb_show_options(m, sb); } static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt) @@ -806,11 +808,14 @@ static int show_vfsmnt(struct seq_file *m, void *v) seq_putc(m, ' '); show_type(m, mnt->mnt_sb); seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); - show_sb_opts(m, mnt->mnt_sb); + err = show_sb_opts(m, mnt->mnt_sb); + if (err) + goto out; show_mnt_opts(m, mnt); if (mnt->mnt_sb->s_op->show_options) err = mnt->mnt_sb->s_op->show_options(m, mnt); seq_puts(m, " 0 0\n"); +out: return err; } @@ -865,10 +870,13 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_putc(m, ' '); mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); - show_sb_opts(m, sb); + err = show_sb_opts(m, sb); + if (err) + goto out; if (sb->s_op->show_options) err = sb->s_op->show_options(m, mnt); seq_putc(m, '\n'); +out: return err; } diff --git a/include/linux/security.h b/include/linux/security.h index 62bd80cb7f8..c8ad8ec684b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -80,6 +80,7 @@ struct xfrm_selector; struct xfrm_policy; struct xfrm_state; struct xfrm_user_sec_ctx; +struct seq_file; extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); extern int cap_netlink_recv(struct sk_buff *skb, int cap); @@ -1331,6 +1332,7 @@ struct security_operations { void (*sb_free_security) (struct super_block *sb); int (*sb_copy_data) (char *orig, char *copy); int (*sb_kern_mount) (struct super_block *sb, void *data); + int (*sb_show_options) (struct seq_file *m, struct super_block *sb); int (*sb_statfs) (struct dentry *dentry); int (*sb_mount) (char *dev_name, struct path *path, char *type, unsigned long flags, void *data); @@ -1610,6 +1612,7 @@ int security_sb_alloc(struct super_block *sb); void security_sb_free(struct super_block *sb); int security_sb_copy_data(char *orig, char *copy); int security_sb_kern_mount(struct super_block *sb, void *data); +int security_sb_show_options(struct seq_file *m, struct super_block *sb); int security_sb_statfs(struct dentry *dentry); int security_sb_mount(char *dev_name, struct path *path, char *type, unsigned long flags, void *data); @@ -1887,6 +1890,12 @@ static inline int security_sb_kern_mount(struct super_block *sb, void *data) return 0; } +static inline int security_sb_show_options(struct seq_file *m, + struct super_block *sb) +{ + return 0; +} + static inline int security_sb_statfs(struct dentry *dentry) { return 0; diff --git a/security/dummy.c b/security/dummy.c index 1db712d99dc..c155f08e9dd 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -194,6 +194,11 @@ static int dummy_sb_kern_mount (struct super_block *sb, void *data) return 0; } +static int dummy_sb_show_options(struct seq_file *m, struct super_block *sb) +{ + return 0; +} + static int dummy_sb_statfs (struct dentry *dentry) { return 0; @@ -1088,6 +1093,7 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sb_free_security); set_to_dummy_if_null(ops, sb_copy_data); set_to_dummy_if_null(ops, sb_kern_mount); + set_to_dummy_if_null(ops, sb_show_options); set_to_dummy_if_null(ops, sb_statfs); set_to_dummy_if_null(ops, sb_mount); set_to_dummy_if_null(ops, sb_check_sb); diff --git a/security/security.c b/security/security.c index 2c0a5876b93..de74fdccde2 100644 --- a/security/security.c +++ b/security/security.c @@ -292,6 +292,11 @@ int security_sb_kern_mount(struct super_block *sb, void *data) return security_ops->sb_kern_mount(sb, data); } +int security_sb_show_options(struct seq_file *m, struct super_block *sb) +{ + return security_ops->sb_show_options(m, sb); +} + int security_sb_statfs(struct dentry *dentry) { return security_ops->sb_statfs(dentry); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 85f74f66576..33dee83fdd2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -9,7 +9,8 @@ * James Morris * * Copyright (C) 2001,2002 Networks Associates Technology, Inc. - * Copyright (C) 2003 Red Hat, Inc., James Morris + * Copyright (C) 2003-2008 Red Hat, Inc., James Morris + * Eric Paris * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. @@ -970,6 +971,57 @@ out_err: return rc; } +void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts) +{ + int i; + char *prefix; + + for (i = 0; i < opts->num_mnt_opts; i++) { + char *has_comma = strchr(opts->mnt_opts[i], ','); + + switch (opts->mnt_opts_flags[i]) { + case CONTEXT_MNT: + prefix = CONTEXT_STR; + break; + case FSCONTEXT_MNT: + prefix = FSCONTEXT_STR; + break; + case ROOTCONTEXT_MNT: + prefix = ROOTCONTEXT_STR; + break; + case DEFCONTEXT_MNT: + prefix = DEFCONTEXT_STR; + break; + default: + BUG(); + }; + /* we need a comma before each option */ + seq_putc(m, ','); + seq_puts(m, prefix); + if (has_comma) + seq_putc(m, '\"'); + seq_puts(m, opts->mnt_opts[i]); + if (has_comma) + seq_putc(m, '\"'); + } +} + +static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) +{ + struct security_mnt_opts opts; + int rc; + + rc = selinux_get_mnt_opts(sb, &opts); + if (rc) + return rc; + + selinux_write_opts(m, &opts); + + security_free_mnt_opts(&opts); + + return rc; +} + static inline u16 inode_mode_to_security_class(umode_t mode) { switch (mode & S_IFMT) { @@ -5365,6 +5417,7 @@ static struct security_operations selinux_ops = { .sb_free_security = selinux_sb_free_security, .sb_copy_data = selinux_sb_copy_data, .sb_kern_mount = selinux_sb_kern_mount, + .sb_show_options = selinux_sb_show_options, .sb_statfs = selinux_sb_statfs, .sb_mount = selinux_mount, .sb_umount = selinux_umount, -- GitLab From b478a9f9889c81e88077d1495daadee64c0af541 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 3 Jul 2008 20:56:04 +0200 Subject: [PATCH 1726/2509] security: remove unused sb_get_mnt_opts hook The sb_get_mnt_opts() hook is unused, and is superseded by the sb_show_options() hook. Signed-off-by: Miklos Szeredi Acked-by: James Morris --- include/linux/security.h | 14 -------------- security/dummy.c | 8 -------- security/security.c | 6 ------ security/selinux/hooks.c | 1 - 4 files changed, 29 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index c8ad8ec684b..43c6357568a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -291,10 +291,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Update module state after a successful pivot. * @old_path contains the path for the old root. * @new_path contains the path for the new root. - * @sb_get_mnt_opts: - * Get the security relevant mount options used for a superblock - * @sb the superblock to get security mount options from - * @opts binary data structure containing all lsm mount data * @sb_set_mnt_opts: * Set the security relevant mount options used for a superblock * @sb the superblock to set security mount options for @@ -1348,8 +1344,6 @@ struct security_operations { struct path *new_path); void (*sb_post_pivotroot) (struct path *old_path, struct path *new_path); - int (*sb_get_mnt_opts) (const struct super_block *sb, - struct security_mnt_opts *opts); int (*sb_set_mnt_opts) (struct super_block *sb, struct security_mnt_opts *opts); void (*sb_clone_mnt_opts) (const struct super_block *oldsb, @@ -1624,8 +1618,6 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint); int security_sb_pivotroot(struct path *old_path, struct path *new_path); void security_sb_post_pivotroot(struct path *old_path, struct path *new_path); -int security_sb_get_mnt_opts(const struct super_block *sb, - struct security_mnt_opts *opts); int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); void security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb); @@ -1942,12 +1934,6 @@ static inline int security_sb_pivotroot(struct path *old_path, static inline void security_sb_post_pivotroot(struct path *old_path, struct path *new_path) { } -static inline int security_sb_get_mnt_opts(const struct super_block *sb, - struct security_mnt_opts *opts) -{ - security_init_mnt_opts(opts); - return 0; -} static inline int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts) diff --git a/security/dummy.c b/security/dummy.c index c155f08e9dd..79385669164 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -252,13 +252,6 @@ static void dummy_sb_post_pivotroot (struct path *old_path, struct path *new_pat return; } -static int dummy_sb_get_mnt_opts(const struct super_block *sb, - struct security_mnt_opts *opts) -{ - security_init_mnt_opts(opts); - return 0; -} - static int dummy_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts) { @@ -1104,7 +1097,6 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sb_post_addmount); set_to_dummy_if_null(ops, sb_pivotroot); set_to_dummy_if_null(ops, sb_post_pivotroot); - set_to_dummy_if_null(ops, sb_get_mnt_opts); set_to_dummy_if_null(ops, sb_set_mnt_opts); set_to_dummy_if_null(ops, sb_clone_mnt_opts); set_to_dummy_if_null(ops, sb_parse_opts_str); diff --git a/security/security.c b/security/security.c index de74fdccde2..28b2860c112 100644 --- a/security/security.c +++ b/security/security.c @@ -348,12 +348,6 @@ void security_sb_post_pivotroot(struct path *old_path, struct path *new_path) security_ops->sb_post_pivotroot(old_path, new_path); } -int security_sb_get_mnt_opts(const struct super_block *sb, - struct security_mnt_opts *opts) -{ - return security_ops->sb_get_mnt_opts(sb, opts); -} - int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts) { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 33dee83fdd2..745a69e74e3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5421,7 +5421,6 @@ static struct security_operations selinux_ops = { .sb_statfs = selinux_sb_statfs, .sb_mount = selinux_mount, .sb_umount = selinux_umount, - .sb_get_mnt_opts = selinux_get_mnt_opts, .sb_set_mnt_opts = selinux_set_mnt_opts, .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, .sb_parse_opts_str = selinux_parse_opts_str, -- GitLab From 5915eb53861c5776cfec33ca4fcc1fd20d66dd27 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 3 Jul 2008 20:56:05 +0200 Subject: [PATCH 1727/2509] security: remove dummy module Remove the dummy module and make the "capability" module the default. Compile and boot tested. Signed-off-by: Miklos Szeredi Acked-by: Serge Hallyn Signed-off-by: James Morris --- security/Kconfig | 10 +- security/Makefile | 11 +- security/capability.c | 1050 +++++++++++++++++++++++++++++++--- security/dummy.c | 1250 ----------------------------------------- security/security.c | 15 +- 5 files changed, 996 insertions(+), 1340 deletions(-) delete mode 100644 security/dummy.c diff --git a/security/Kconfig b/security/Kconfig index 49b51f96489..77def9f9f5f 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -73,17 +73,9 @@ config SECURITY_NETWORK_XFRM IPSec. If you are unsure how to answer this question, answer N. -config SECURITY_CAPABILITIES - bool "Default Linux Capabilities" - depends on SECURITY - default y - help - This enables the "default" Linux capabilities functionality. - If you are unsure how to answer this question, answer Y. - config SECURITY_FILE_CAPABILITIES bool "File POSIX Capabilities (EXPERIMENTAL)" - depends on (SECURITY=n || SECURITY_CAPABILITIES!=n) && EXPERIMENTAL + depends on SECURITY && EXPERIMENTAL default n help This enables filesystem capabilities, allowing you to give diff --git a/security/Makefile b/security/Makefile index 7ef1107a728..f65426099aa 100644 --- a/security/Makefile +++ b/security/Makefile @@ -6,16 +6,13 @@ obj-$(CONFIG_KEYS) += keys/ subdir-$(CONFIG_SECURITY_SELINUX) += selinux subdir-$(CONFIG_SECURITY_SMACK) += smack -# if we don't select a security model, use the default capabilities -ifneq ($(CONFIG_SECURITY),y) +# always enable default capabilities obj-y += commoncap.o -endif # Object file lists -obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o +obj-$(CONFIG_SECURITY) += security.o capability.o inode.o # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o -obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o -obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o -obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o +obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o diff --git a/security/capability.c b/security/capability.c index 38ac54e3aed..6e0671c8201 100644 --- a/security/capability.c +++ b/security/capability.c @@ -1,6 +1,8 @@ /* * Capabilities Linux Security Module * + * This is the default security module in case no other module is loaded. + * * 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 @@ -8,75 +10,995 @@ * */ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct security_operations capability_ops = { - .ptrace = cap_ptrace, - .capget = cap_capget, - .capset_check = cap_capset_check, - .capset_set = cap_capset_set, - .capable = cap_capable, - .settime = cap_settime, - .netlink_send = cap_netlink_send, - .netlink_recv = cap_netlink_recv, - - .bprm_apply_creds = cap_bprm_apply_creds, - .bprm_set_security = cap_bprm_set_security, - .bprm_secureexec = cap_bprm_secureexec, - - .inode_setxattr = cap_inode_setxattr, - .inode_removexattr = cap_inode_removexattr, - .inode_need_killpriv = cap_inode_need_killpriv, - .inode_killpriv = cap_inode_killpriv, - - .task_setscheduler = cap_task_setscheduler, - .task_setioprio = cap_task_setioprio, - .task_setnice = cap_task_setnice, - .task_post_setuid = cap_task_post_setuid, - .task_prctl = cap_task_prctl, - .task_reparent_to_init = cap_task_reparent_to_init, - - .syslog = cap_syslog, - - .vm_enough_memory = cap_vm_enough_memory, -}; -/* flag to keep track of how we were registered */ -static int secondary; +static int cap_acct(struct file *file) +{ + return 0; +} + +static int cap_sysctl(ctl_table *table, int op) +{ + return 0; +} + +static int cap_quotactl(int cmds, int type, int id, struct super_block *sb) +{ + return 0; +} + +static int cap_quota_on(struct dentry *dentry) +{ + return 0; +} + +static int cap_bprm_alloc_security(struct linux_binprm *bprm) +{ + return 0; +} + +static void cap_bprm_free_security(struct linux_binprm *bprm) +{ +} + +static void cap_bprm_post_apply_creds(struct linux_binprm *bprm) +{ +} + +static int cap_bprm_check_security(struct linux_binprm *bprm) +{ + return 0; +} + +static int cap_sb_alloc_security(struct super_block *sb) +{ + return 0; +} + +static void cap_sb_free_security(struct super_block *sb) +{ +} + +static int cap_sb_copy_data(char *orig, char *copy) +{ + return 0; +} + +static int cap_sb_kern_mount(struct super_block *sb, void *data) +{ + return 0; +} + +static int cap_sb_show_options(struct seq_file *m, struct super_block *sb) +{ + return 0; +} + +static int cap_sb_statfs(struct dentry *dentry) +{ + return 0; +} + +static int cap_sb_mount(char *dev_name, struct path *path, char *type, + unsigned long flags, void *data) +{ + return 0; +} + +static int cap_sb_check_sb(struct vfsmount *mnt, struct path *path) +{ + return 0; +} + +static int cap_sb_umount(struct vfsmount *mnt, int flags) +{ + return 0; +} + +static void cap_sb_umount_close(struct vfsmount *mnt) +{ +} + +static void cap_sb_umount_busy(struct vfsmount *mnt) +{ +} + +static void cap_sb_post_remount(struct vfsmount *mnt, unsigned long flags, + void *data) +{ +} + +static void cap_sb_post_addmount(struct vfsmount *mnt, struct path *path) +{ +} + +static int cap_sb_pivotroot(struct path *old_path, struct path *new_path) +{ + return 0; +} + +static void cap_sb_post_pivotroot(struct path *old_path, struct path *new_path) +{ +} + +static int cap_sb_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) +{ + if (unlikely(opts->num_mnt_opts)) + return -EOPNOTSUPP; + return 0; +} + +static void cap_sb_clone_mnt_opts(const struct super_block *oldsb, + struct super_block *newsb) +{ +} + +static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return 0; +} + +static int cap_inode_alloc_security(struct inode *inode) +{ + return 0; +} + +static void cap_inode_free_security(struct inode *inode) +{ +} + +static int cap_inode_init_security(struct inode *inode, struct inode *dir, + char **name, void **value, size_t *len) +{ + return -EOPNOTSUPP; +} + +static int cap_inode_create(struct inode *inode, struct dentry *dentry, + int mask) +{ + return 0; +} + +static int cap_inode_link(struct dentry *old_dentry, struct inode *inode, + struct dentry *new_dentry) +{ + return 0; +} + +static int cap_inode_unlink(struct inode *inode, struct dentry *dentry) +{ + return 0; +} + +static int cap_inode_symlink(struct inode *inode, struct dentry *dentry, + const char *name) +{ + return 0; +} + +static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry, + int mask) +{ + return 0; +} + +static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry) +{ + return 0; +} + +static int cap_inode_mknod(struct inode *inode, struct dentry *dentry, + int mode, dev_t dev) +{ + return 0; +} + +static int cap_inode_rename(struct inode *old_inode, struct dentry *old_dentry, + struct inode *new_inode, struct dentry *new_dentry) +{ + return 0; +} + +static int cap_inode_readlink(struct dentry *dentry) +{ + return 0; +} + +static int cap_inode_follow_link(struct dentry *dentry, + struct nameidata *nameidata) +{ + return 0; +} + +static int cap_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) +{ + return 0; +} + +static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr) +{ + return 0; +} + +static int cap_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) +{ + return 0; +} + +static void cap_inode_delete(struct inode *ino) +{ +} + +static void cap_inode_post_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ +} + +static int cap_inode_getxattr(struct dentry *dentry, const char *name) +{ + return 0; +} + +static int cap_inode_listxattr(struct dentry *dentry) +{ + return 0; +} + +static int cap_inode_getsecurity(const struct inode *inode, const char *name, + void **buffer, bool alloc) +{ + return -EOPNOTSUPP; +} + +static int cap_inode_setsecurity(struct inode *inode, const char *name, + const void *value, size_t size, int flags) +{ + return -EOPNOTSUPP; +} + +static int cap_inode_listsecurity(struct inode *inode, char *buffer, + size_t buffer_size) +{ + return 0; +} + +static void cap_inode_getsecid(const struct inode *inode, u32 *secid) +{ + *secid = 0; +} + +static int cap_file_permission(struct file *file, int mask) +{ + return 0; +} + +static int cap_file_alloc_security(struct file *file) +{ + return 0; +} + +static void cap_file_free_security(struct file *file) +{ +} + +static int cap_file_ioctl(struct file *file, unsigned int command, + unsigned long arg) +{ + return 0; +} + +static int cap_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags, + unsigned long addr, unsigned long addr_only) +{ + if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) + return -EACCES; + return 0; +} + +static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, + unsigned long prot) +{ + return 0; +} + +static int cap_file_lock(struct file *file, unsigned int cmd) +{ + return 0; +} + +static int cap_file_fcntl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return 0; +} + +static int cap_file_set_fowner(struct file *file) +{ + return 0; +} + +static int cap_file_send_sigiotask(struct task_struct *tsk, + struct fown_struct *fown, int sig) +{ + return 0; +} + +static int cap_file_receive(struct file *file) +{ + return 0; +} + +static int cap_dentry_open(struct file *file) +{ + return 0; +} + +static int cap_task_create(unsigned long clone_flags) +{ + return 0; +} + +static int cap_task_alloc_security(struct task_struct *p) +{ + return 0; +} + +static void cap_task_free_security(struct task_struct *p) +{ +} + +static int cap_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) +{ + return 0; +} + +static int cap_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) +{ + return 0; +} -static int capability_disable; -module_param_named(disable, capability_disable, int, 0); +static int cap_task_setpgid(struct task_struct *p, pid_t pgid) +{ + return 0; +} -static int __init capability_init (void) +static int cap_task_getpgid(struct task_struct *p) { - if (capability_disable) { - printk(KERN_INFO "Capabilities disabled at initialization\n"); - return 0; - } - /* register ourselves with the security framework */ - if (register_security (&capability_ops)) { - /* try registering with primary module */ - if (mod_reg_security (KBUILD_MODNAME, &capability_ops)) { - printk (KERN_INFO "Failure registering capabilities " - "with primary security module.\n"); - return -EINVAL; - } - secondary = 1; - } - printk (KERN_INFO "Capability LSM initialized%s\n", - secondary ? " as secondary" : ""); return 0; } -security_initcall (capability_init); +static int cap_task_getsid(struct task_struct *p) +{ + return 0; +} + +static void cap_task_getsecid(struct task_struct *p, u32 *secid) +{ + *secid = 0; +} + +static int cap_task_setgroups(struct group_info *group_info) +{ + return 0; +} + +static int cap_task_getioprio(struct task_struct *p) +{ + return 0; +} + +static int cap_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +{ + return 0; +} + +static int cap_task_getscheduler(struct task_struct *p) +{ + return 0; +} + +static int cap_task_movememory(struct task_struct *p) +{ + return 0; +} + +static int cap_task_wait(struct task_struct *p) +{ + return 0; +} + +static int cap_task_kill(struct task_struct *p, struct siginfo *info, + int sig, u32 secid) +{ + return 0; +} + +static void cap_task_to_inode(struct task_struct *p, struct inode *inode) +{ +} + +static int cap_ipc_permission(struct kern_ipc_perm *ipcp, short flag) +{ + return 0; +} + +static void cap_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) +{ + *secid = 0; +} + +static int cap_msg_msg_alloc_security(struct msg_msg *msg) +{ + return 0; +} + +static void cap_msg_msg_free_security(struct msg_msg *msg) +{ +} + +static int cap_msg_queue_alloc_security(struct msg_queue *msq) +{ + return 0; +} + +static void cap_msg_queue_free_security(struct msg_queue *msq) +{ +} + +static int cap_msg_queue_associate(struct msg_queue *msq, int msqflg) +{ + return 0; +} + +static int cap_msg_queue_msgctl(struct msg_queue *msq, int cmd) +{ + return 0; +} + +static int cap_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, + int msgflg) +{ + return 0; +} + +static int cap_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, + struct task_struct *target, long type, int mode) +{ + return 0; +} + +static int cap_shm_alloc_security(struct shmid_kernel *shp) +{ + return 0; +} + +static void cap_shm_free_security(struct shmid_kernel *shp) +{ +} + +static int cap_shm_associate(struct shmid_kernel *shp, int shmflg) +{ + return 0; +} + +static int cap_shm_shmctl(struct shmid_kernel *shp, int cmd) +{ + return 0; +} + +static int cap_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, + int shmflg) +{ + return 0; +} + +static int cap_sem_alloc_security(struct sem_array *sma) +{ + return 0; +} + +static void cap_sem_free_security(struct sem_array *sma) +{ +} + +static int cap_sem_associate(struct sem_array *sma, int semflg) +{ + return 0; +} + +static int cap_sem_semctl(struct sem_array *sma, int cmd) +{ + return 0; +} + +static int cap_sem_semop(struct sem_array *sma, struct sembuf *sops, + unsigned nsops, int alter) +{ + return 0; +} + +#ifdef CONFIG_SECURITY_NETWORK +static int cap_unix_stream_connect(struct socket *sock, struct socket *other, + struct sock *newsk) +{ + return 0; +} + +static int cap_unix_may_send(struct socket *sock, struct socket *other) +{ + return 0; +} + +static int cap_socket_create(int family, int type, int protocol, int kern) +{ + return 0; +} + +static int cap_socket_post_create(struct socket *sock, int family, int type, + int protocol, int kern) +{ + return 0; +} + +static int cap_socket_bind(struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int cap_socket_connect(struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int cap_socket_listen(struct socket *sock, int backlog) +{ + return 0; +} + +static int cap_socket_accept(struct socket *sock, struct socket *newsock) +{ + return 0; +} + +static void cap_socket_post_accept(struct socket *sock, struct socket *newsock) +{ +} + +static int cap_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) +{ + return 0; +} + +static int cap_socket_recvmsg(struct socket *sock, struct msghdr *msg, + int size, int flags) +{ + return 0; +} + +static int cap_socket_getsockname(struct socket *sock) +{ + return 0; +} + +static int cap_socket_getpeername(struct socket *sock) +{ + return 0; +} + +static int cap_socket_setsockopt(struct socket *sock, int level, int optname) +{ + return 0; +} + +static int cap_socket_getsockopt(struct socket *sock, int level, int optname) +{ + return 0; +} + +static int cap_socket_shutdown(struct socket *sock, int how) +{ + return 0; +} + +static int cap_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + return 0; +} + +static int cap_socket_getpeersec_stream(struct socket *sock, + char __user *optval, + int __user *optlen, unsigned len) +{ + return -ENOPROTOOPT; +} + +static int cap_socket_getpeersec_dgram(struct socket *sock, + struct sk_buff *skb, u32 *secid) +{ + return -ENOPROTOOPT; +} + +static int cap_sk_alloc_security(struct sock *sk, int family, gfp_t priority) +{ + return 0; +} + +static void cap_sk_free_security(struct sock *sk) +{ +} + +static void cap_sk_clone_security(const struct sock *sk, struct sock *newsk) +{ +} + +static void cap_sk_getsecid(struct sock *sk, u32 *secid) +{ +} + +static void cap_sock_graft(struct sock *sk, struct socket *parent) +{ +} + +static int cap_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct request_sock *req) +{ + return 0; +} + +static void cap_inet_csk_clone(struct sock *newsk, + const struct request_sock *req) +{ +} + +static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb) +{ +} + +static void cap_req_classify_flow(const struct request_sock *req, + struct flowi *fl) +{ +} +#endif /* CONFIG_SECURITY_NETWORK */ + +#ifdef CONFIG_SECURITY_NETWORK_XFRM +static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, + struct xfrm_user_sec_ctx *sec_ctx) +{ + return 0; +} + +static int cap_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx, + struct xfrm_sec_ctx **new_ctxp) +{ + return 0; +} + +static void cap_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx) +{ +} + +static int cap_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx) +{ + return 0; +} + +static int cap_xfrm_state_alloc_security(struct xfrm_state *x, + struct xfrm_user_sec_ctx *sec_ctx, + u32 secid) +{ + return 0; +} + +static void cap_xfrm_state_free_security(struct xfrm_state *x) +{ +} + +static int cap_xfrm_state_delete_security(struct xfrm_state *x) +{ + return 0; +} + +static int cap_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 sk_sid, u8 dir) +{ + return 0; +} + +static int cap_xfrm_state_pol_flow_match(struct xfrm_state *x, + struct xfrm_policy *xp, + struct flowi *fl) +{ + return 1; +} + +static int cap_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) +{ + return 0; +} + +#endif /* CONFIG_SECURITY_NETWORK_XFRM */ +static int cap_register_security(const char *name, + struct security_operations *ops) +{ + return -EINVAL; +} + +static void cap_d_instantiate(struct dentry *dentry, struct inode *inode) +{ +} + +static int cap_getprocattr(struct task_struct *p, char *name, char **value) +{ + return -EINVAL; +} + +static int cap_setprocattr(struct task_struct *p, char *name, void *value, + size_t size) +{ + return -EINVAL; +} + +static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +{ + return -EOPNOTSUPP; +} + +static int cap_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) +{ + return -EOPNOTSUPP; +} + +static void cap_release_secctx(char *secdata, u32 seclen) +{ +} + +#ifdef CONFIG_KEYS +static int cap_key_alloc(struct key *key, struct task_struct *ctx, + unsigned long flags) +{ + return 0; +} + +static void cap_key_free(struct key *key) +{ +} + +static int cap_key_permission(key_ref_t key_ref, struct task_struct *context, + key_perm_t perm) +{ + return 0; +} + +static int cap_key_getsecurity(struct key *key, char **_buffer) +{ + *_buffer = NULL; + return 0; +} + +#endif /* CONFIG_KEYS */ + +#ifdef CONFIG_AUDIT +static int cap_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) +{ + return 0; +} + +static int cap_audit_rule_known(struct audit_krule *krule) +{ + return 0; +} + +static int cap_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, + struct audit_context *actx) +{ + return 0; +} + +static void cap_audit_rule_free(void *lsmrule) +{ +} +#endif /* CONFIG_AUDIT */ + +struct security_operations default_security_ops = { + .name = "default", +}; + +#define set_to_cap_if_null(ops, function) \ + do { \ + if (!ops->function) { \ + ops->function = cap_##function; \ + pr_debug("Had to override the " #function \ + " security operation with the default.\n");\ + } \ + } while (0) + +void security_fixup_ops(struct security_operations *ops) +{ + set_to_cap_if_null(ops, ptrace); + set_to_cap_if_null(ops, capget); + set_to_cap_if_null(ops, capset_check); + set_to_cap_if_null(ops, capset_set); + set_to_cap_if_null(ops, acct); + set_to_cap_if_null(ops, capable); + set_to_cap_if_null(ops, quotactl); + set_to_cap_if_null(ops, quota_on); + set_to_cap_if_null(ops, sysctl); + set_to_cap_if_null(ops, syslog); + set_to_cap_if_null(ops, settime); + set_to_cap_if_null(ops, vm_enough_memory); + set_to_cap_if_null(ops, bprm_alloc_security); + set_to_cap_if_null(ops, bprm_free_security); + set_to_cap_if_null(ops, bprm_apply_creds); + set_to_cap_if_null(ops, bprm_post_apply_creds); + set_to_cap_if_null(ops, bprm_set_security); + set_to_cap_if_null(ops, bprm_check_security); + set_to_cap_if_null(ops, bprm_secureexec); + set_to_cap_if_null(ops, sb_alloc_security); + set_to_cap_if_null(ops, sb_free_security); + set_to_cap_if_null(ops, sb_copy_data); + set_to_cap_if_null(ops, sb_kern_mount); + set_to_cap_if_null(ops, sb_show_options); + set_to_cap_if_null(ops, sb_statfs); + set_to_cap_if_null(ops, sb_mount); + set_to_cap_if_null(ops, sb_check_sb); + set_to_cap_if_null(ops, sb_umount); + set_to_cap_if_null(ops, sb_umount_close); + set_to_cap_if_null(ops, sb_umount_busy); + set_to_cap_if_null(ops, sb_post_remount); + set_to_cap_if_null(ops, sb_post_addmount); + set_to_cap_if_null(ops, sb_pivotroot); + set_to_cap_if_null(ops, sb_post_pivotroot); + set_to_cap_if_null(ops, sb_set_mnt_opts); + set_to_cap_if_null(ops, sb_clone_mnt_opts); + set_to_cap_if_null(ops, sb_parse_opts_str); + set_to_cap_if_null(ops, inode_alloc_security); + set_to_cap_if_null(ops, inode_free_security); + set_to_cap_if_null(ops, inode_init_security); + set_to_cap_if_null(ops, inode_create); + set_to_cap_if_null(ops, inode_link); + set_to_cap_if_null(ops, inode_unlink); + set_to_cap_if_null(ops, inode_symlink); + set_to_cap_if_null(ops, inode_mkdir); + set_to_cap_if_null(ops, inode_rmdir); + set_to_cap_if_null(ops, inode_mknod); + set_to_cap_if_null(ops, inode_rename); + set_to_cap_if_null(ops, inode_readlink); + set_to_cap_if_null(ops, inode_follow_link); + set_to_cap_if_null(ops, inode_permission); + set_to_cap_if_null(ops, inode_setattr); + set_to_cap_if_null(ops, inode_getattr); + set_to_cap_if_null(ops, inode_delete); + set_to_cap_if_null(ops, inode_setxattr); + set_to_cap_if_null(ops, inode_post_setxattr); + set_to_cap_if_null(ops, inode_getxattr); + set_to_cap_if_null(ops, inode_listxattr); + set_to_cap_if_null(ops, inode_removexattr); + set_to_cap_if_null(ops, inode_need_killpriv); + set_to_cap_if_null(ops, inode_killpriv); + set_to_cap_if_null(ops, inode_getsecurity); + set_to_cap_if_null(ops, inode_setsecurity); + set_to_cap_if_null(ops, inode_listsecurity); + set_to_cap_if_null(ops, inode_getsecid); + set_to_cap_if_null(ops, file_permission); + set_to_cap_if_null(ops, file_alloc_security); + set_to_cap_if_null(ops, file_free_security); + set_to_cap_if_null(ops, file_ioctl); + set_to_cap_if_null(ops, file_mmap); + set_to_cap_if_null(ops, file_mprotect); + set_to_cap_if_null(ops, file_lock); + set_to_cap_if_null(ops, file_fcntl); + set_to_cap_if_null(ops, file_set_fowner); + set_to_cap_if_null(ops, file_send_sigiotask); + set_to_cap_if_null(ops, file_receive); + set_to_cap_if_null(ops, dentry_open); + set_to_cap_if_null(ops, task_create); + set_to_cap_if_null(ops, task_alloc_security); + set_to_cap_if_null(ops, task_free_security); + set_to_cap_if_null(ops, task_setuid); + set_to_cap_if_null(ops, task_post_setuid); + set_to_cap_if_null(ops, task_setgid); + set_to_cap_if_null(ops, task_setpgid); + set_to_cap_if_null(ops, task_getpgid); + set_to_cap_if_null(ops, task_getsid); + set_to_cap_if_null(ops, task_getsecid); + set_to_cap_if_null(ops, task_setgroups); + set_to_cap_if_null(ops, task_setnice); + set_to_cap_if_null(ops, task_setioprio); + set_to_cap_if_null(ops, task_getioprio); + set_to_cap_if_null(ops, task_setrlimit); + set_to_cap_if_null(ops, task_setscheduler); + set_to_cap_if_null(ops, task_getscheduler); + set_to_cap_if_null(ops, task_movememory); + set_to_cap_if_null(ops, task_wait); + set_to_cap_if_null(ops, task_kill); + set_to_cap_if_null(ops, task_prctl); + set_to_cap_if_null(ops, task_reparent_to_init); + set_to_cap_if_null(ops, task_to_inode); + set_to_cap_if_null(ops, ipc_permission); + set_to_cap_if_null(ops, ipc_getsecid); + set_to_cap_if_null(ops, msg_msg_alloc_security); + set_to_cap_if_null(ops, msg_msg_free_security); + set_to_cap_if_null(ops, msg_queue_alloc_security); + set_to_cap_if_null(ops, msg_queue_free_security); + set_to_cap_if_null(ops, msg_queue_associate); + set_to_cap_if_null(ops, msg_queue_msgctl); + set_to_cap_if_null(ops, msg_queue_msgsnd); + set_to_cap_if_null(ops, msg_queue_msgrcv); + set_to_cap_if_null(ops, shm_alloc_security); + set_to_cap_if_null(ops, shm_free_security); + set_to_cap_if_null(ops, shm_associate); + set_to_cap_if_null(ops, shm_shmctl); + set_to_cap_if_null(ops, shm_shmat); + set_to_cap_if_null(ops, sem_alloc_security); + set_to_cap_if_null(ops, sem_free_security); + set_to_cap_if_null(ops, sem_associate); + set_to_cap_if_null(ops, sem_semctl); + set_to_cap_if_null(ops, sem_semop); + set_to_cap_if_null(ops, netlink_send); + set_to_cap_if_null(ops, netlink_recv); + set_to_cap_if_null(ops, register_security); + set_to_cap_if_null(ops, d_instantiate); + set_to_cap_if_null(ops, getprocattr); + set_to_cap_if_null(ops, setprocattr); + set_to_cap_if_null(ops, secid_to_secctx); + set_to_cap_if_null(ops, secctx_to_secid); + set_to_cap_if_null(ops, release_secctx); +#ifdef CONFIG_SECURITY_NETWORK + set_to_cap_if_null(ops, unix_stream_connect); + set_to_cap_if_null(ops, unix_may_send); + set_to_cap_if_null(ops, socket_create); + set_to_cap_if_null(ops, socket_post_create); + set_to_cap_if_null(ops, socket_bind); + set_to_cap_if_null(ops, socket_connect); + set_to_cap_if_null(ops, socket_listen); + set_to_cap_if_null(ops, socket_accept); + set_to_cap_if_null(ops, socket_post_accept); + set_to_cap_if_null(ops, socket_sendmsg); + set_to_cap_if_null(ops, socket_recvmsg); + set_to_cap_if_null(ops, socket_getsockname); + set_to_cap_if_null(ops, socket_getpeername); + set_to_cap_if_null(ops, socket_setsockopt); + set_to_cap_if_null(ops, socket_getsockopt); + set_to_cap_if_null(ops, socket_shutdown); + set_to_cap_if_null(ops, socket_sock_rcv_skb); + set_to_cap_if_null(ops, socket_getpeersec_stream); + set_to_cap_if_null(ops, socket_getpeersec_dgram); + set_to_cap_if_null(ops, sk_alloc_security); + set_to_cap_if_null(ops, sk_free_security); + set_to_cap_if_null(ops, sk_clone_security); + set_to_cap_if_null(ops, sk_getsecid); + set_to_cap_if_null(ops, sock_graft); + set_to_cap_if_null(ops, inet_conn_request); + set_to_cap_if_null(ops, inet_csk_clone); + set_to_cap_if_null(ops, inet_conn_established); + set_to_cap_if_null(ops, req_classify_flow); +#endif /* CONFIG_SECURITY_NETWORK */ +#ifdef CONFIG_SECURITY_NETWORK_XFRM + set_to_cap_if_null(ops, xfrm_policy_alloc_security); + set_to_cap_if_null(ops, xfrm_policy_clone_security); + set_to_cap_if_null(ops, xfrm_policy_free_security); + set_to_cap_if_null(ops, xfrm_policy_delete_security); + set_to_cap_if_null(ops, xfrm_state_alloc_security); + set_to_cap_if_null(ops, xfrm_state_free_security); + set_to_cap_if_null(ops, xfrm_state_delete_security); + set_to_cap_if_null(ops, xfrm_policy_lookup); + set_to_cap_if_null(ops, xfrm_state_pol_flow_match); + set_to_cap_if_null(ops, xfrm_decode_session); +#endif /* CONFIG_SECURITY_NETWORK_XFRM */ +#ifdef CONFIG_KEYS + set_to_cap_if_null(ops, key_alloc); + set_to_cap_if_null(ops, key_free); + set_to_cap_if_null(ops, key_permission); + set_to_cap_if_null(ops, key_getsecurity); +#endif /* CONFIG_KEYS */ +#ifdef CONFIG_AUDIT + set_to_cap_if_null(ops, audit_rule_init); + set_to_cap_if_null(ops, audit_rule_known); + set_to_cap_if_null(ops, audit_rule_match); + set_to_cap_if_null(ops, audit_rule_free); +#endif +} diff --git a/security/dummy.c b/security/dummy.c deleted file mode 100644 index 79385669164..00000000000 --- a/security/dummy.c +++ /dev/null @@ -1,1250 +0,0 @@ -/* - * Stub functions for the default security function pointers in case no - * security model is loaded. - * - * Copyright (C) 2001 WireX Communications, Inc - * Copyright (C) 2001-2002 Greg Kroah-Hartman - * Copyright (C) 2001 Networks Associates Technology, 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int dummy_ptrace (struct task_struct *parent, struct task_struct *child, - unsigned int mode) -{ - return 0; -} - -static int dummy_capget (struct task_struct *target, kernel_cap_t * effective, - kernel_cap_t * inheritable, kernel_cap_t * permitted) -{ - if (target->euid == 0) { - cap_set_full(*permitted); - cap_set_init_eff(*effective); - } else { - cap_clear(*permitted); - cap_clear(*effective); - } - - cap_clear(*inheritable); - - if (target->fsuid != 0) { - *permitted = cap_drop_fs_set(*permitted); - *effective = cap_drop_fs_set(*effective); - } - return 0; -} - -static int dummy_capset_check (struct task_struct *target, - kernel_cap_t * effective, - kernel_cap_t * inheritable, - kernel_cap_t * permitted) -{ - return -EPERM; -} - -static void dummy_capset_set (struct task_struct *target, - kernel_cap_t * effective, - kernel_cap_t * inheritable, - kernel_cap_t * permitted) -{ - return; -} - -static int dummy_acct (struct file *file) -{ - return 0; -} - -static int dummy_capable (struct task_struct *tsk, int cap) -{ - if (cap_raised (tsk->cap_effective, cap)) - return 0; - return -EPERM; -} - -static int dummy_sysctl (ctl_table * table, int op) -{ - return 0; -} - -static int dummy_quotactl (int cmds, int type, int id, struct super_block *sb) -{ - return 0; -} - -static int dummy_quota_on (struct dentry *dentry) -{ - return 0; -} - -static int dummy_syslog (int type) -{ - if ((type != 3 && type != 10) && current->euid) - return -EPERM; - return 0; -} - -static int dummy_settime(struct timespec *ts, struct timezone *tz) -{ - if (!capable(CAP_SYS_TIME)) - return -EPERM; - return 0; -} - -static int dummy_vm_enough_memory(struct mm_struct *mm, long pages) -{ - int cap_sys_admin = 0; - - if (dummy_capable(current, CAP_SYS_ADMIN) == 0) - cap_sys_admin = 1; - return __vm_enough_memory(mm, pages, cap_sys_admin); -} - -static int dummy_bprm_alloc_security (struct linux_binprm *bprm) -{ - return 0; -} - -static void dummy_bprm_free_security (struct linux_binprm *bprm) -{ - return; -} - -static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) -{ - if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) { - set_dumpable(current->mm, suid_dumpable); - - if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) { - bprm->e_uid = current->uid; - bprm->e_gid = current->gid; - } - } - - current->suid = current->euid = current->fsuid = bprm->e_uid; - current->sgid = current->egid = current->fsgid = bprm->e_gid; - - dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted); -} - -static void dummy_bprm_post_apply_creds (struct linux_binprm *bprm) -{ - return; -} - -static int dummy_bprm_set_security (struct linux_binprm *bprm) -{ - return 0; -} - -static int dummy_bprm_check_security (struct linux_binprm *bprm) -{ - return 0; -} - -static int dummy_bprm_secureexec (struct linux_binprm *bprm) -{ - /* The new userland will simply use the value provided - in the AT_SECURE field to decide whether secure mode - is required. Hence, this logic is required to preserve - the legacy decision algorithm used by the old userland. */ - return (current->euid != current->uid || - current->egid != current->gid); -} - -static int dummy_sb_alloc_security (struct super_block *sb) -{ - return 0; -} - -static void dummy_sb_free_security (struct super_block *sb) -{ - return; -} - -static int dummy_sb_copy_data (char *orig, char *copy) -{ - return 0; -} - -static int dummy_sb_kern_mount (struct super_block *sb, void *data) -{ - return 0; -} - -static int dummy_sb_show_options(struct seq_file *m, struct super_block *sb) -{ - return 0; -} - -static int dummy_sb_statfs (struct dentry *dentry) -{ - return 0; -} - -static int dummy_sb_mount (char *dev_name, struct path *path, char *type, - unsigned long flags, void *data) -{ - return 0; -} - -static int dummy_sb_check_sb (struct vfsmount *mnt, struct path *path) -{ - return 0; -} - -static int dummy_sb_umount (struct vfsmount *mnt, int flags) -{ - return 0; -} - -static void dummy_sb_umount_close (struct vfsmount *mnt) -{ - return; -} - -static void dummy_sb_umount_busy (struct vfsmount *mnt) -{ - return; -} - -static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags, - void *data) -{ - return; -} - - -static void dummy_sb_post_addmount (struct vfsmount *mnt, struct path *path) -{ - return; -} - -static int dummy_sb_pivotroot (struct path *old_path, struct path *new_path) -{ - return 0; -} - -static void dummy_sb_post_pivotroot (struct path *old_path, struct path *new_path) -{ - return; -} - -static int dummy_sb_set_mnt_opts(struct super_block *sb, - struct security_mnt_opts *opts) -{ - if (unlikely(opts->num_mnt_opts)) - return -EOPNOTSUPP; - return 0; -} - -static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb, - struct super_block *newsb) -{ - return; -} - -static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) -{ - return 0; -} - -static int dummy_inode_alloc_security (struct inode *inode) -{ - return 0; -} - -static void dummy_inode_free_security (struct inode *inode) -{ - return; -} - -static int dummy_inode_init_security (struct inode *inode, struct inode *dir, - char **name, void **value, size_t *len) -{ - return -EOPNOTSUPP; -} - -static int dummy_inode_create (struct inode *inode, struct dentry *dentry, - int mask) -{ - return 0; -} - -static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode, - struct dentry *new_dentry) -{ - return 0; -} - -static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry, - const char *name) -{ - return 0; -} - -static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry, - int mask) -{ - return 0; -} - -static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry, - int mode, dev_t dev) -{ - return 0; -} - -static int dummy_inode_rename (struct inode *old_inode, - struct dentry *old_dentry, - struct inode *new_inode, - struct dentry *new_dentry) -{ - return 0; -} - -static int dummy_inode_readlink (struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_follow_link (struct dentry *dentry, - struct nameidata *nameidata) -{ - return 0; -} - -static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata *nd) -{ - return 0; -} - -static int dummy_inode_setattr (struct dentry *dentry, struct iattr *iattr) -{ - return 0; -} - -static int dummy_inode_getattr (struct vfsmount *mnt, struct dentry *dentry) -{ - return 0; -} - -static void dummy_inode_delete (struct inode *ino) -{ - return; -} - -static int dummy_inode_setxattr (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; -} - -static void dummy_inode_post_setxattr (struct dentry *dentry, const char *name, - const void *value, size_t size, - int flags) -{ -} - -static int dummy_inode_getxattr (struct dentry *dentry, const char *name) -{ - return 0; -} - -static int dummy_inode_listxattr (struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_removexattr (struct dentry *dentry, const char *name) -{ - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; -} - -static int dummy_inode_need_killpriv(struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_killpriv(struct dentry *dentry) -{ - return 0; -} - -static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) -{ - return -EOPNOTSUPP; -} - -static int dummy_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) -{ - return -EOPNOTSUPP; -} - -static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) -{ - return 0; -} - -static void dummy_inode_getsecid(const struct inode *inode, u32 *secid) -{ - *secid = 0; -} - -static int dummy_file_permission (struct file *file, int mask) -{ - return 0; -} - -static int dummy_file_alloc_security (struct file *file) -{ - return 0; -} - -static void dummy_file_free_security (struct file *file) -{ - return; -} - -static int dummy_file_ioctl (struct file *file, unsigned int command, - unsigned long arg) -{ - return 0; -} - -static int dummy_file_mmap (struct file *file, unsigned long reqprot, - unsigned long prot, - unsigned long flags, - unsigned long addr, - unsigned long addr_only) -{ - if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) - return -EACCES; - return 0; -} - -static int dummy_file_mprotect (struct vm_area_struct *vma, - unsigned long reqprot, - unsigned long prot) -{ - return 0; -} - -static int dummy_file_lock (struct file *file, unsigned int cmd) -{ - return 0; -} - -static int dummy_file_fcntl (struct file *file, unsigned int cmd, - unsigned long arg) -{ - return 0; -} - -static int dummy_file_set_fowner (struct file *file) -{ - return 0; -} - -static int dummy_file_send_sigiotask (struct task_struct *tsk, - struct fown_struct *fown, int sig) -{ - return 0; -} - -static int dummy_file_receive (struct file *file) -{ - return 0; -} - -static int dummy_dentry_open (struct file *file) -{ - return 0; -} - -static int dummy_task_create (unsigned long clone_flags) -{ - return 0; -} - -static int dummy_task_alloc_security (struct task_struct *p) -{ - return 0; -} - -static void dummy_task_free_security (struct task_struct *p) -{ - return; -} - -static int dummy_task_setuid (uid_t id0, uid_t id1, uid_t id2, int flags) -{ - return 0; -} - -static int dummy_task_post_setuid (uid_t id0, uid_t id1, uid_t id2, int flags) -{ - dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted); - return 0; -} - -static int dummy_task_setgid (gid_t id0, gid_t id1, gid_t id2, int flags) -{ - return 0; -} - -static int dummy_task_setpgid (struct task_struct *p, pid_t pgid) -{ - return 0; -} - -static int dummy_task_getpgid (struct task_struct *p) -{ - return 0; -} - -static int dummy_task_getsid (struct task_struct *p) -{ - return 0; -} - -static void dummy_task_getsecid (struct task_struct *p, u32 *secid) -{ - *secid = 0; -} - -static int dummy_task_setgroups (struct group_info *group_info) -{ - return 0; -} - -static int dummy_task_setnice (struct task_struct *p, int nice) -{ - return 0; -} - -static int dummy_task_setioprio (struct task_struct *p, int ioprio) -{ - return 0; -} - -static int dummy_task_getioprio (struct task_struct *p) -{ - return 0; -} - -static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) -{ - return 0; -} - -static int dummy_task_setscheduler (struct task_struct *p, int policy, - struct sched_param *lp) -{ - return 0; -} - -static int dummy_task_getscheduler (struct task_struct *p) -{ - return 0; -} - -static int dummy_task_movememory (struct task_struct *p) -{ - return 0; -} - -static int dummy_task_wait (struct task_struct *p) -{ - return 0; -} - -static int dummy_task_kill (struct task_struct *p, struct siginfo *info, - int sig, u32 secid) -{ - return 0; -} - -static int dummy_task_prctl (int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5, long *rc_p) -{ - switch (option) { - case PR_CAPBSET_READ: - *rc_p = (cap_valid(arg2) ? 1 : -EINVAL); - break; - case PR_GET_KEEPCAPS: - *rc_p = issecure(SECURE_KEEP_CAPS); - break; - case PR_SET_KEEPCAPS: - if (arg2 > 1) - *rc_p = -EINVAL; - else if (arg2) - current->securebits |= issecure_mask(SECURE_KEEP_CAPS); - else - current->securebits &= - ~issecure_mask(SECURE_KEEP_CAPS); - break; - default: - return 0; - } - - return 1; -} - -static void dummy_task_reparent_to_init (struct task_struct *p) -{ - p->euid = p->fsuid = 0; - return; -} - -static void dummy_task_to_inode(struct task_struct *p, struct inode *inode) -{ } - -static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) -{ - return 0; -} - -static void dummy_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) -{ - *secid = 0; -} - -static int dummy_msg_msg_alloc_security (struct msg_msg *msg) -{ - return 0; -} - -static void dummy_msg_msg_free_security (struct msg_msg *msg) -{ - return; -} - -static int dummy_msg_queue_alloc_security (struct msg_queue *msq) -{ - return 0; -} - -static void dummy_msg_queue_free_security (struct msg_queue *msq) -{ - return; -} - -static int dummy_msg_queue_associate (struct msg_queue *msq, - int msqflg) -{ - return 0; -} - -static int dummy_msg_queue_msgctl (struct msg_queue *msq, int cmd) -{ - return 0; -} - -static int dummy_msg_queue_msgsnd (struct msg_queue *msq, struct msg_msg *msg, - int msgflg) -{ - return 0; -} - -static int dummy_msg_queue_msgrcv (struct msg_queue *msq, struct msg_msg *msg, - struct task_struct *target, long type, - int mode) -{ - return 0; -} - -static int dummy_shm_alloc_security (struct shmid_kernel *shp) -{ - return 0; -} - -static void dummy_shm_free_security (struct shmid_kernel *shp) -{ - return; -} - -static int dummy_shm_associate (struct shmid_kernel *shp, int shmflg) -{ - return 0; -} - -static int dummy_shm_shmctl (struct shmid_kernel *shp, int cmd) -{ - return 0; -} - -static int dummy_shm_shmat (struct shmid_kernel *shp, char __user *shmaddr, - int shmflg) -{ - return 0; -} - -static int dummy_sem_alloc_security (struct sem_array *sma) -{ - return 0; -} - -static void dummy_sem_free_security (struct sem_array *sma) -{ - return; -} - -static int dummy_sem_associate (struct sem_array *sma, int semflg) -{ - return 0; -} - -static int dummy_sem_semctl (struct sem_array *sma, int cmd) -{ - return 0; -} - -static int dummy_sem_semop (struct sem_array *sma, - struct sembuf *sops, unsigned nsops, int alter) -{ - return 0; -} - -static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb) -{ - NETLINK_CB(skb).eff_cap = current->cap_effective; - return 0; -} - -static int dummy_netlink_recv (struct sk_buff *skb, int cap) -{ - if (!cap_raised (NETLINK_CB (skb).eff_cap, cap)) - return -EPERM; - return 0; -} - -#ifdef CONFIG_SECURITY_NETWORK -static int dummy_unix_stream_connect (struct socket *sock, - struct socket *other, - struct sock *newsk) -{ - return 0; -} - -static int dummy_unix_may_send (struct socket *sock, - struct socket *other) -{ - return 0; -} - -static int dummy_socket_create (int family, int type, - int protocol, int kern) -{ - return 0; -} - -static int dummy_socket_post_create (struct socket *sock, int family, int type, - int protocol, int kern) -{ - return 0; -} - -static int dummy_socket_bind (struct socket *sock, struct sockaddr *address, - int addrlen) -{ - return 0; -} - -static int dummy_socket_connect (struct socket *sock, struct sockaddr *address, - int addrlen) -{ - return 0; -} - -static int dummy_socket_listen (struct socket *sock, int backlog) -{ - return 0; -} - -static int dummy_socket_accept (struct socket *sock, struct socket *newsock) -{ - return 0; -} - -static void dummy_socket_post_accept (struct socket *sock, - struct socket *newsock) -{ - return; -} - -static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg, - int size) -{ - return 0; -} - -static int dummy_socket_recvmsg (struct socket *sock, struct msghdr *msg, - int size, int flags) -{ - return 0; -} - -static int dummy_socket_getsockname (struct socket *sock) -{ - return 0; -} - -static int dummy_socket_getpeername (struct socket *sock) -{ - return 0; -} - -static int dummy_socket_setsockopt (struct socket *sock, int level, int optname) -{ - return 0; -} - -static int dummy_socket_getsockopt (struct socket *sock, int level, int optname) -{ - return 0; -} - -static int dummy_socket_shutdown (struct socket *sock, int how) -{ - return 0; -} - -static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb) -{ - return 0; -} - -static int dummy_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) -{ - return -ENOPROTOOPT; -} - -static int dummy_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) -{ - return -ENOPROTOOPT; -} - -static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t priority) -{ - return 0; -} - -static inline void dummy_sk_free_security (struct sock *sk) -{ -} - -static inline void dummy_sk_clone_security (const struct sock *sk, struct sock *newsk) -{ -} - -static inline void dummy_sk_getsecid(struct sock *sk, u32 *secid) -{ -} - -static inline void dummy_sock_graft(struct sock* sk, struct socket *parent) -{ -} - -static inline int dummy_inet_conn_request(struct sock *sk, - struct sk_buff *skb, struct request_sock *req) -{ - return 0; -} - -static inline void dummy_inet_csk_clone(struct sock *newsk, - const struct request_sock *req) -{ -} - -static inline void dummy_inet_conn_established(struct sock *sk, - struct sk_buff *skb) -{ -} - -static inline void dummy_req_classify_flow(const struct request_sock *req, - struct flowi *fl) -{ -} -#endif /* CONFIG_SECURITY_NETWORK */ - -#ifdef CONFIG_SECURITY_NETWORK_XFRM -static int dummy_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, - struct xfrm_user_sec_ctx *sec_ctx) -{ - return 0; -} - -static inline int dummy_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx, - struct xfrm_sec_ctx **new_ctxp) -{ - return 0; -} - -static void dummy_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx) -{ -} - -static int dummy_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx) -{ - return 0; -} - -static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx, u32 secid) -{ - return 0; -} - -static void dummy_xfrm_state_free_security(struct xfrm_state *x) -{ -} - -static int dummy_xfrm_state_delete_security(struct xfrm_state *x) -{ - return 0; -} - -static int dummy_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, - u32 sk_sid, u8 dir) -{ - return 0; -} - -static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x, - struct xfrm_policy *xp, struct flowi *fl) -{ - return 1; -} - -static int dummy_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) -{ - return 0; -} - -#endif /* CONFIG_SECURITY_NETWORK_XFRM */ -static int dummy_register_security (const char *name, struct security_operations *ops) -{ - return -EINVAL; -} - -static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) -{ - return; -} - -static int dummy_getprocattr(struct task_struct *p, char *name, char **value) -{ - return -EINVAL; -} - -static int dummy_setprocattr(struct task_struct *p, char *name, void *value, size_t size) -{ - return -EINVAL; -} - -static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) -{ - return -EOPNOTSUPP; -} - -static int dummy_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) -{ - return -EOPNOTSUPP; -} - -static void dummy_release_secctx(char *secdata, u32 seclen) -{ -} - -#ifdef CONFIG_KEYS -static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx, - unsigned long flags) -{ - return 0; -} - -static inline void dummy_key_free(struct key *key) -{ -} - -static inline int dummy_key_permission(key_ref_t key_ref, - struct task_struct *context, - key_perm_t perm) -{ - return 0; -} - -static int dummy_key_getsecurity(struct key *key, char **_buffer) -{ - *_buffer = NULL; - return 0; -} - -#endif /* CONFIG_KEYS */ - -#ifdef CONFIG_AUDIT -static inline int dummy_audit_rule_init(u32 field, u32 op, char *rulestr, - void **lsmrule) -{ - return 0; -} - -static inline int dummy_audit_rule_known(struct audit_krule *krule) -{ - return 0; -} - -static inline int dummy_audit_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule, - struct audit_context *actx) -{ - return 0; -} - -static inline void dummy_audit_rule_free(void *lsmrule) -{ } - -#endif /* CONFIG_AUDIT */ - -struct security_operations dummy_security_ops = { - .name = "dummy", -}; - -#define set_to_dummy_if_null(ops, function) \ - do { \ - if (!ops->function) { \ - ops->function = dummy_##function; \ - pr_debug("Had to override the " #function \ - " security operation with the dummy one.\n");\ - } \ - } while (0) - -void security_fixup_ops (struct security_operations *ops) -{ - set_to_dummy_if_null(ops, ptrace); - set_to_dummy_if_null(ops, capget); - set_to_dummy_if_null(ops, capset_check); - set_to_dummy_if_null(ops, capset_set); - set_to_dummy_if_null(ops, acct); - set_to_dummy_if_null(ops, capable); - set_to_dummy_if_null(ops, quotactl); - set_to_dummy_if_null(ops, quota_on); - set_to_dummy_if_null(ops, sysctl); - set_to_dummy_if_null(ops, syslog); - set_to_dummy_if_null(ops, settime); - set_to_dummy_if_null(ops, vm_enough_memory); - set_to_dummy_if_null(ops, bprm_alloc_security); - set_to_dummy_if_null(ops, bprm_free_security); - set_to_dummy_if_null(ops, bprm_apply_creds); - set_to_dummy_if_null(ops, bprm_post_apply_creds); - set_to_dummy_if_null(ops, bprm_set_security); - set_to_dummy_if_null(ops, bprm_check_security); - set_to_dummy_if_null(ops, bprm_secureexec); - set_to_dummy_if_null(ops, sb_alloc_security); - set_to_dummy_if_null(ops, sb_free_security); - set_to_dummy_if_null(ops, sb_copy_data); - set_to_dummy_if_null(ops, sb_kern_mount); - set_to_dummy_if_null(ops, sb_show_options); - set_to_dummy_if_null(ops, sb_statfs); - set_to_dummy_if_null(ops, sb_mount); - set_to_dummy_if_null(ops, sb_check_sb); - set_to_dummy_if_null(ops, sb_umount); - set_to_dummy_if_null(ops, sb_umount_close); - set_to_dummy_if_null(ops, sb_umount_busy); - set_to_dummy_if_null(ops, sb_post_remount); - set_to_dummy_if_null(ops, sb_post_addmount); - set_to_dummy_if_null(ops, sb_pivotroot); - set_to_dummy_if_null(ops, sb_post_pivotroot); - set_to_dummy_if_null(ops, sb_set_mnt_opts); - set_to_dummy_if_null(ops, sb_clone_mnt_opts); - set_to_dummy_if_null(ops, sb_parse_opts_str); - set_to_dummy_if_null(ops, inode_alloc_security); - set_to_dummy_if_null(ops, inode_free_security); - set_to_dummy_if_null(ops, inode_init_security); - set_to_dummy_if_null(ops, inode_create); - set_to_dummy_if_null(ops, inode_link); - set_to_dummy_if_null(ops, inode_unlink); - set_to_dummy_if_null(ops, inode_symlink); - set_to_dummy_if_null(ops, inode_mkdir); - set_to_dummy_if_null(ops, inode_rmdir); - set_to_dummy_if_null(ops, inode_mknod); - set_to_dummy_if_null(ops, inode_rename); - set_to_dummy_if_null(ops, inode_readlink); - set_to_dummy_if_null(ops, inode_follow_link); - set_to_dummy_if_null(ops, inode_permission); - set_to_dummy_if_null(ops, inode_setattr); - set_to_dummy_if_null(ops, inode_getattr); - set_to_dummy_if_null(ops, inode_delete); - set_to_dummy_if_null(ops, inode_setxattr); - set_to_dummy_if_null(ops, inode_post_setxattr); - set_to_dummy_if_null(ops, inode_getxattr); - set_to_dummy_if_null(ops, inode_listxattr); - set_to_dummy_if_null(ops, inode_removexattr); - set_to_dummy_if_null(ops, inode_need_killpriv); - set_to_dummy_if_null(ops, inode_killpriv); - set_to_dummy_if_null(ops, inode_getsecurity); - set_to_dummy_if_null(ops, inode_setsecurity); - set_to_dummy_if_null(ops, inode_listsecurity); - set_to_dummy_if_null(ops, inode_getsecid); - set_to_dummy_if_null(ops, file_permission); - set_to_dummy_if_null(ops, file_alloc_security); - set_to_dummy_if_null(ops, file_free_security); - set_to_dummy_if_null(ops, file_ioctl); - set_to_dummy_if_null(ops, file_mmap); - set_to_dummy_if_null(ops, file_mprotect); - set_to_dummy_if_null(ops, file_lock); - set_to_dummy_if_null(ops, file_fcntl); - set_to_dummy_if_null(ops, file_set_fowner); - set_to_dummy_if_null(ops, file_send_sigiotask); - set_to_dummy_if_null(ops, file_receive); - set_to_dummy_if_null(ops, dentry_open); - set_to_dummy_if_null(ops, task_create); - set_to_dummy_if_null(ops, task_alloc_security); - set_to_dummy_if_null(ops, task_free_security); - set_to_dummy_if_null(ops, task_setuid); - set_to_dummy_if_null(ops, task_post_setuid); - set_to_dummy_if_null(ops, task_setgid); - set_to_dummy_if_null(ops, task_setpgid); - set_to_dummy_if_null(ops, task_getpgid); - set_to_dummy_if_null(ops, task_getsid); - set_to_dummy_if_null(ops, task_getsecid); - set_to_dummy_if_null(ops, task_setgroups); - set_to_dummy_if_null(ops, task_setnice); - set_to_dummy_if_null(ops, task_setioprio); - set_to_dummy_if_null(ops, task_getioprio); - set_to_dummy_if_null(ops, task_setrlimit); - set_to_dummy_if_null(ops, task_setscheduler); - set_to_dummy_if_null(ops, task_getscheduler); - set_to_dummy_if_null(ops, task_movememory); - set_to_dummy_if_null(ops, task_wait); - set_to_dummy_if_null(ops, task_kill); - set_to_dummy_if_null(ops, task_prctl); - set_to_dummy_if_null(ops, task_reparent_to_init); - set_to_dummy_if_null(ops, task_to_inode); - set_to_dummy_if_null(ops, ipc_permission); - set_to_dummy_if_null(ops, ipc_getsecid); - set_to_dummy_if_null(ops, msg_msg_alloc_security); - set_to_dummy_if_null(ops, msg_msg_free_security); - set_to_dummy_if_null(ops, msg_queue_alloc_security); - set_to_dummy_if_null(ops, msg_queue_free_security); - set_to_dummy_if_null(ops, msg_queue_associate); - set_to_dummy_if_null(ops, msg_queue_msgctl); - set_to_dummy_if_null(ops, msg_queue_msgsnd); - set_to_dummy_if_null(ops, msg_queue_msgrcv); - set_to_dummy_if_null(ops, shm_alloc_security); - set_to_dummy_if_null(ops, shm_free_security); - set_to_dummy_if_null(ops, shm_associate); - set_to_dummy_if_null(ops, shm_shmctl); - set_to_dummy_if_null(ops, shm_shmat); - set_to_dummy_if_null(ops, sem_alloc_security); - set_to_dummy_if_null(ops, sem_free_security); - set_to_dummy_if_null(ops, sem_associate); - set_to_dummy_if_null(ops, sem_semctl); - set_to_dummy_if_null(ops, sem_semop); - set_to_dummy_if_null(ops, netlink_send); - set_to_dummy_if_null(ops, netlink_recv); - set_to_dummy_if_null(ops, register_security); - set_to_dummy_if_null(ops, d_instantiate); - set_to_dummy_if_null(ops, getprocattr); - set_to_dummy_if_null(ops, setprocattr); - set_to_dummy_if_null(ops, secid_to_secctx); - set_to_dummy_if_null(ops, secctx_to_secid); - set_to_dummy_if_null(ops, release_secctx); -#ifdef CONFIG_SECURITY_NETWORK - set_to_dummy_if_null(ops, unix_stream_connect); - set_to_dummy_if_null(ops, unix_may_send); - set_to_dummy_if_null(ops, socket_create); - set_to_dummy_if_null(ops, socket_post_create); - set_to_dummy_if_null(ops, socket_bind); - set_to_dummy_if_null(ops, socket_connect); - set_to_dummy_if_null(ops, socket_listen); - set_to_dummy_if_null(ops, socket_accept); - set_to_dummy_if_null(ops, socket_post_accept); - set_to_dummy_if_null(ops, socket_sendmsg); - set_to_dummy_if_null(ops, socket_recvmsg); - set_to_dummy_if_null(ops, socket_getsockname); - set_to_dummy_if_null(ops, socket_getpeername); - set_to_dummy_if_null(ops, socket_setsockopt); - set_to_dummy_if_null(ops, socket_getsockopt); - set_to_dummy_if_null(ops, socket_shutdown); - set_to_dummy_if_null(ops, socket_sock_rcv_skb); - set_to_dummy_if_null(ops, socket_getpeersec_stream); - set_to_dummy_if_null(ops, socket_getpeersec_dgram); - set_to_dummy_if_null(ops, sk_alloc_security); - set_to_dummy_if_null(ops, sk_free_security); - set_to_dummy_if_null(ops, sk_clone_security); - set_to_dummy_if_null(ops, sk_getsecid); - set_to_dummy_if_null(ops, sock_graft); - set_to_dummy_if_null(ops, inet_conn_request); - set_to_dummy_if_null(ops, inet_csk_clone); - set_to_dummy_if_null(ops, inet_conn_established); - set_to_dummy_if_null(ops, req_classify_flow); - #endif /* CONFIG_SECURITY_NETWORK */ -#ifdef CONFIG_SECURITY_NETWORK_XFRM - set_to_dummy_if_null(ops, xfrm_policy_alloc_security); - set_to_dummy_if_null(ops, xfrm_policy_clone_security); - set_to_dummy_if_null(ops, xfrm_policy_free_security); - set_to_dummy_if_null(ops, xfrm_policy_delete_security); - set_to_dummy_if_null(ops, xfrm_state_alloc_security); - set_to_dummy_if_null(ops, xfrm_state_free_security); - set_to_dummy_if_null(ops, xfrm_state_delete_security); - set_to_dummy_if_null(ops, xfrm_policy_lookup); - set_to_dummy_if_null(ops, xfrm_state_pol_flow_match); - set_to_dummy_if_null(ops, xfrm_decode_session); -#endif /* CONFIG_SECURITY_NETWORK_XFRM */ -#ifdef CONFIG_KEYS - set_to_dummy_if_null(ops, key_alloc); - set_to_dummy_if_null(ops, key_free); - set_to_dummy_if_null(ops, key_permission); - set_to_dummy_if_null(ops, key_getsecurity); -#endif /* CONFIG_KEYS */ -#ifdef CONFIG_AUDIT - set_to_dummy_if_null(ops, audit_rule_init); - set_to_dummy_if_null(ops, audit_rule_known); - set_to_dummy_if_null(ops, audit_rule_match); - set_to_dummy_if_null(ops, audit_rule_free); -#endif -} - diff --git a/security/security.c b/security/security.c index 28b2860c112..30b0278de39 100644 --- a/security/security.c +++ b/security/security.c @@ -20,8 +20,8 @@ /* Boot-time LSM user choice */ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; -/* things that live in dummy.c */ -extern struct security_operations dummy_security_ops; +/* things that live in capability.c */ +extern struct security_operations default_security_ops; extern void security_fixup_ops(struct security_operations *ops); struct security_operations *security_ops; /* Initialized to NULL */ @@ -57,13 +57,8 @@ int __init security_init(void) { printk(KERN_INFO "Security Framework initialized\n"); - if (verify(&dummy_security_ops)) { - printk(KERN_ERR "%s could not verify " - "dummy_security_ops structure.\n", __func__); - return -EIO; - } - - security_ops = &dummy_security_ops; + security_fixup_ops(&default_security_ops); + security_ops = &default_security_ops; do_security_initcalls(); return 0; @@ -122,7 +117,7 @@ int register_security(struct security_operations *ops) return -EINVAL; } - if (security_ops != &dummy_security_ops) + if (security_ops != &default_security_ops) return -EAGAIN; security_ops = ops; -- GitLab From 93cbace7a058bce7f99319ef6ceff4b78cf45051 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 10 Jul 2008 11:10:09 +0200 Subject: [PATCH 1728/2509] security: remove dummy module fix Fix small oversight in "security: remove dummy module": CONFIG_SECURITY_FILE_CAPABILITIES doesn't depend on CONFIG_SECURITY Signed-off-by: Miklos Szeredi Signed-off-by: James Morris --- security/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/Kconfig b/security/Kconfig index 77def9f9f5f..62ed4717d33 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -75,7 +75,7 @@ config SECURITY_NETWORK_XFRM config SECURITY_FILE_CAPABILITIES bool "File POSIX Capabilities (EXPERIMENTAL)" - depends on SECURITY && EXPERIMENTAL + depends on EXPERIMENTAL default n help This enables filesystem capabilities, allowing you to give -- GitLab From 6f0f0fd496333777d53daff21a4e3b28c4d03a6d Mon Sep 17 00:00:00 2001 From: James Morris Date: Thu, 10 Jul 2008 17:02:07 +0900 Subject: [PATCH 1729/2509] security: remove register_security hook The register security hook is no longer required, as the capability module is always registered. LSMs wishing to stack capability as a secondary module should do so explicitly. Signed-off-by: James Morris Acked-by: Stephen Smalley Acked-by: Greg Kroah-Hartman --- include/linux/security.h | 10 ---------- security/capability.c | 7 ------- security/root_plug.c | 9 --------- security/security.c | 29 ----------------------------- security/selinux/hooks.c | 32 +++++--------------------------- security/smack/smack_lsm.c | 23 ----------------------- 6 files changed, 5 insertions(+), 105 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 43c6357568a..31c8851ec5d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1239,11 +1239,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @pages contains the number of pages. * Return 0 if permission is granted. * - * @register_security: - * allow module stacking. - * @name contains the name of the security module being stacked. - * @ops contains a pointer to the struct security_operations of the module to stack. - * * @secid_to_secctx: * Convert secid to security context. * @secid contains the security ID. @@ -1471,10 +1466,6 @@ struct security_operations { int (*netlink_send) (struct sock *sk, struct sk_buff *skb); int (*netlink_recv) (struct sk_buff *skb, int cap); - /* allow module stacking */ - int (*register_security) (const char *name, - struct security_operations *ops); - void (*d_instantiate) (struct dentry *dentry, struct inode *inode); int (*getprocattr) (struct task_struct *p, char *name, char **value); @@ -1564,7 +1555,6 @@ struct security_operations { extern int security_init(void); extern int security_module_enable(struct security_operations *ops); extern int register_security(struct security_operations *ops); -extern int mod_reg_security(const char *name, struct security_operations *ops); extern struct dentry *securityfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); diff --git a/security/capability.c b/security/capability.c index 6e0671c8201..5b01c0b0242 100644 --- a/security/capability.c +++ b/security/capability.c @@ -721,12 +721,6 @@ static int cap_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) } #endif /* CONFIG_SECURITY_NETWORK_XFRM */ -static int cap_register_security(const char *name, - struct security_operations *ops) -{ - return -EINVAL; -} - static void cap_d_instantiate(struct dentry *dentry, struct inode *inode) { } @@ -940,7 +934,6 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, sem_semop); set_to_cap_if_null(ops, netlink_send); set_to_cap_if_null(ops, netlink_recv); - set_to_cap_if_null(ops, register_security); set_to_cap_if_null(ops, d_instantiate); set_to_cap_if_null(ops, getprocattr); set_to_cap_if_null(ops, setprocattr); diff --git a/security/root_plug.c b/security/root_plug.c index a41cf42a4fa..be0ebec2580 100644 --- a/security/root_plug.c +++ b/security/root_plug.c @@ -28,9 +28,6 @@ #include #include -/* flag to keep track of how we were registered */ -static int secondary; - /* default is a generic type of usb to serial converter */ static int vendor_id = 0x0557; static int product_id = 0x2008; @@ -97,13 +94,7 @@ static int __init rootplug_init (void) if (register_security (&rootplug_security_ops)) { printk (KERN_INFO "Failure registering Root Plug module with the kernel\n"); - /* try registering with primary module */ - if (mod_reg_security (MY_NAME, &rootplug_security_ops)) { - printk (KERN_INFO "Failure registering Root Plug " - " module with primary security module.\n"); return -EINVAL; - } - secondary = 1; } printk (KERN_INFO "Root Plug module initialized, " "vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id); diff --git a/security/security.c b/security/security.c index 30b0278de39..59f23b5918b 100644 --- a/security/security.c +++ b/security/security.c @@ -125,35 +125,6 @@ int register_security(struct security_operations *ops) return 0; } -/** - * mod_reg_security - allows security modules to be "stacked" - * @name: a pointer to a string with the name of the security_options to be registered - * @ops: a pointer to the struct security_options that is to be registered - * - * This function allows security modules to be stacked if the currently loaded - * security module allows this to happen. It passes the @name and @ops to the - * register_security function of the currently loaded security module. - * - * The return value depends on the currently loaded security module, with 0 as - * success. - */ -int mod_reg_security(const char *name, struct security_operations *ops) -{ - if (verify(ops)) { - printk(KERN_INFO "%s could not verify " - "security operations.\n", __func__); - return -EINVAL; - } - - if (ops == security_ops) { - printk(KERN_INFO "%s security operations " - "already registered.\n", __func__); - return -EINVAL; - } - - return security_ops->register_security(name, ops); -} - /* Security operations */ int security_ptrace(struct task_struct *parent, struct task_struct *child, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 745a69e74e3..91200feb3f9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -126,13 +126,11 @@ __setup("selinux=", selinux_enabled_setup); int selinux_enabled = 1; #endif -/* Original (dummy) security module. */ -static struct security_operations *original_ops; -/* Minimal support for a secondary security module, - just to allow the use of the dummy or capability modules. - The owlsm module can alternatively be used as a secondary - module as long as CONFIG_OWLSM_FD is not enabled. */ +/* + * Minimal support for a secondary security module, + * just to allow the use of the capability module. + */ static struct security_operations *secondary_ops; /* Lists of inode and superblock security structures initialized @@ -5115,24 +5113,6 @@ static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) *secid = isec->sid; } -/* module stacking operations */ -static int selinux_register_security(const char *name, struct security_operations *ops) -{ - if (secondary_ops != original_ops) { - printk(KERN_ERR "%s: There is already a secondary security " - "module registered.\n", __func__); - return -EINVAL; - } - - secondary_ops = ops; - - printk(KERN_INFO "%s: Registering secondary module %s\n", - __func__, - name); - - return 0; -} - static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) { if (inode) @@ -5517,8 +5497,6 @@ static struct security_operations selinux_ops = { .sem_semctl = selinux_sem_semctl, .sem_semop = selinux_sem_semop, - .register_security = selinux_register_security, - .d_instantiate = selinux_d_instantiate, .getprocattr = selinux_getprocattr, @@ -5612,7 +5590,7 @@ static __init int selinux_init(void) 0, SLAB_PANIC, NULL); avc_init(); - original_ops = secondary_ops = security_ops; + secondary_ops = security_ops; if (!secondary_ops) panic("SELinux: No initial security operations\n"); if (register_security(&selinux_ops)) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 3c7150b3493..ee5a51cbc5e 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1822,27 +1822,6 @@ static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) *secid = smack_to_secid(smack); } -/* module stacking operations */ - -/** - * smack_register_security - stack capability module - * @name: module name - * @ops: module operations - ignored - * - * Allow the capability module to register. - */ -static int smack_register_security(const char *name, - struct security_operations *ops) -{ - if (strcmp(name, "capability") != 0) - return -EINVAL; - - printk(KERN_INFO "%s: Registering secondary module %s\n", - __func__, name); - - return 0; -} - /** * smack_d_instantiate - Make sure the blob is correct on an inode * @opt_dentry: unused @@ -2673,8 +2652,6 @@ struct security_operations smack_ops = { .netlink_send = cap_netlink_send, .netlink_recv = cap_netlink_recv, - .register_security = smack_register_security, - .d_instantiate = smack_d_instantiate, .getprocattr = smack_getprocattr, -- GitLab From f7c5dda23a9f4b7f8977612154daef44cc0f423b Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 10 Jul 2008 17:49:11 +0200 Subject: [PATCH 1730/2509] ALSA: hda: 92hd71bxx PC Beep Added volume controls for the analog PC Beep on 92hd71bxx codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a6d138831e2..08cb77f5188 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -825,6 +825,9 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), { } /* end */ -- GitLab From 4090dffb1438e03a434e3747b14321440561d956 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:02:45 +0200 Subject: [PATCH 1731/2509] ALSA: hda - Fix internal mic vref pin setup Set the vref80 to the internal mic pin 0x12 for Cx5045. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 95e3367d887..71c4072c926 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -686,7 +686,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { static struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* HP, Amp */ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -- GitLab From 86376df6ad0f1a7a1118cd53b0cfd679524f5436 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:04:05 +0200 Subject: [PATCH 1732/2509] ALSA: hda - Fix missing init for unsol events on micsense model Fixed the missing initialization for unsolicited events on Cx5045 micsense model. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 71c4072c926..8295994665e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -962,6 +962,7 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops.init = cxt5045_init; break; case CXT5045_LAPTOP_MICSENSE: + codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; spec->input_mux = &cxt5045_capture_source; spec->num_init_verbs = 2; spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; -- GitLab From 9e4641541e9681a568483133813332cfafa34d86 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:05:25 +0200 Subject: [PATCH 1733/2509] ALSA: hda - Fix FSC V5505 model model=laptop-hpmicsense matches better to FSC V5505 laptop. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 8295994665e..7c1eb23f0ce 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -910,7 +910,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { 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), - SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", CXT5045_LAPTOP_HPSENSE), + SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", + CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), -- GitLab From 787dba37a6ff5c80c67f37c081712a6e4af92e25 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 12 Jul 2008 12:12:20 +0200 Subject: [PATCH 1734/2509] ALSA: ALSA driver for SGI HAL2 audio device This patch adds a new ALSA driver for the audio device found inside many older SGI workstation (Indy, Indigo2). The hardware uses a SGI custom chip, which feeds two codec chips, an IEC chip and a synth chip. Currently only one of the codecs is supported. This driver already has the same functionality as the HAL2 OSS driver and will replace it. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/mips/Kconfig | 7 + sound/mips/Makefile | 2 + sound/mips/hal2.c | 947 ++++++++++++++++++++++++++++++++++++++++++++ sound/mips/hal2.h | 245 ++++++++++++ 4 files changed, 1201 insertions(+) create mode 100644 sound/mips/hal2.c create mode 100644 sound/mips/hal2.h diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index bb26f6cf4c0..2a61cade4ac 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -9,6 +9,13 @@ menuconfig SND_MIPS if SND_MIPS +config SND_SGI_HAL2 + tristate "SGI HAL2 Audio" + depends on SGI_HAS_HAL2 + help + Sound support for the SGI Indy and Indigo2 Workstation. + + config SND_AU1X00 tristate "Au1x00 AC97 Port Driver" depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 diff --git a/sound/mips/Makefile b/sound/mips/Makefile index 47afed971fb..63f4a9c0a8d 100644 --- a/sound/mips/Makefile +++ b/sound/mips/Makefile @@ -3,6 +3,8 @@ # snd-au1x00-objs := au1x00.o +snd-sgi-hal2-objs := hal2.o # Toplevel Module Dependency obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o +obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c new file mode 100644 index 00000000000..db495be0186 --- /dev/null +++ b/sound/mips/hal2.c @@ -0,0 +1,947 @@ +/* + * Driver for A2 audio system used in SGI machines + * Copyright (c) 2008 Thomas Bogendoerfer + * + * Based on OSS code from Ladislav Michl , which + * was based on code from Ulf Carlsson + * + * 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. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "hal2.h" + +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ +static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ + +module_param(index, int, 0444); +MODULE_PARM_DESC(index, "Index value for SGI HAL2 soundcard."); +module_param(id, charp, 0444); +MODULE_PARM_DESC(id, "ID string for SGI HAL2 soundcard."); +MODULE_DESCRIPTION("ALSA driver for SGI HAL2 audio"); +MODULE_AUTHOR("Thomas Bogendoerfer"); +MODULE_LICENSE("GPL"); + + +#define H2_BLOCK_SIZE 1024 +#define H2_BUF_SIZE 16384 + +struct hal2_pbus { + struct hpc3_pbus_dmacregs *pbus; + int pbusnr; + unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */ +}; + +struct hal2_desc { + struct hpc_dma_desc desc; + u32 pad; /* padding */ +}; + +struct hal2_codec { + struct snd_pcm_indirect pcm_indirect; + struct snd_pcm_substream *substream; + + unsigned char *buffer; + dma_addr_t buffer_dma; + struct hal2_desc *desc; + dma_addr_t desc_dma; + int desc_count; + struct hal2_pbus pbus; + int voices; /* mono/stereo */ + unsigned int sample_rate; + unsigned int master; /* Master frequency */ + unsigned short mod; /* MOD value */ + unsigned short inc; /* INC value */ +}; + +#define H2_MIX_OUTPUT_ATT 0 +#define H2_MIX_INPUT_GAIN 1 + +struct snd_hal2 { + struct snd_card *card; + + struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */ + struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */ + struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */ + struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */ + + struct hal2_codec dac; + struct hal2_codec adc; +}; + +#define H2_INDIRECT_WAIT(regs) while (hal2_read(®s->isr) & H2_ISR_TSTATUS); + +#define H2_READ_ADDR(addr) (addr | (1<<7)) +#define H2_WRITE_ADDR(addr) (addr) + +static inline u32 hal2_read(u32 *reg) +{ + return __raw_readl(reg); +} + +static inline void hal2_write(u32 val, u32 *reg) +{ + __raw_writel(val, reg); +} + + +static u32 hal2_i_read32(struct snd_hal2 *hal2, u16 addr) +{ + u32 ret; + struct hal2_ctl_regs *regs = hal2->ctl_regs; + + hal2_write(H2_READ_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); + ret = hal2_read(®s->idr0) & 0xffff; + hal2_write(H2_READ_ADDR(addr) | 0x1, ®s->iar); + H2_INDIRECT_WAIT(regs); + ret |= (hal2_read(®s->idr0) & 0xffff) << 16; + return ret; +} + +static void hal2_i_write16(struct snd_hal2 *hal2, u16 addr, u16 val) +{ + struct hal2_ctl_regs *regs = hal2->ctl_regs; + + hal2_write(val, ®s->idr0); + hal2_write(0, ®s->idr1); + hal2_write(0, ®s->idr2); + hal2_write(0, ®s->idr3); + hal2_write(H2_WRITE_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); +} + +static void hal2_i_write32(struct snd_hal2 *hal2, u16 addr, u32 val) +{ + struct hal2_ctl_regs *regs = hal2->ctl_regs; + + hal2_write(val & 0xffff, ®s->idr0); + hal2_write(val >> 16, ®s->idr1); + hal2_write(0, ®s->idr2); + hal2_write(0, ®s->idr3); + hal2_write(H2_WRITE_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); +} + +static void hal2_i_setbit16(struct snd_hal2 *hal2, u16 addr, u16 bit) +{ + struct hal2_ctl_regs *regs = hal2->ctl_regs; + + hal2_write(H2_READ_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); + hal2_write((hal2_read(®s->idr0) & 0xffff) | bit, ®s->idr0); + hal2_write(0, ®s->idr1); + hal2_write(0, ®s->idr2); + hal2_write(0, ®s->idr3); + hal2_write(H2_WRITE_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); +} + +static void hal2_i_clearbit16(struct snd_hal2 *hal2, u16 addr, u16 bit) +{ + struct hal2_ctl_regs *regs = hal2->ctl_regs; + + hal2_write(H2_READ_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); + hal2_write((hal2_read(®s->idr0) & 0xffff) & ~bit, ®s->idr0); + hal2_write(0, ®s->idr1); + hal2_write(0, ®s->idr2); + hal2_write(0, ®s->idr3); + hal2_write(H2_WRITE_ADDR(addr), ®s->iar); + H2_INDIRECT_WAIT(regs); +} + +static int hal2_gain_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + switch ((int)kcontrol->private_value) { + case H2_MIX_OUTPUT_ATT: + uinfo->value.integer.max = 31; + break; + case H2_MIX_INPUT_GAIN: + uinfo->value.integer.max = 15; + break; + } + return 0; +} + +static int hal2_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol); + u32 tmp; + int l, r; + + switch ((int)kcontrol->private_value) { + case H2_MIX_OUTPUT_ATT: + tmp = hal2_i_read32(hal2, H2I_DAC_C2); + if (tmp & H2I_C2_MUTE) { + l = 0; + r = 0; + } else { + l = 31 - ((tmp >> H2I_C2_L_ATT_SHIFT) & 31); + r = 31 - ((tmp >> H2I_C2_R_ATT_SHIFT) & 31); + } + break; + case H2_MIX_INPUT_GAIN: + tmp = hal2_i_read32(hal2, H2I_ADC_C2); + l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15; + r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15; + break; + } + ucontrol->value.integer.value[0] = l; + ucontrol->value.integer.value[1] = r; + + return 0; +} + +static int hal2_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol); + u32 old, new; + int l, r; + + l = ucontrol->value.integer.value[0]; + r = ucontrol->value.integer.value[1]; + + switch ((int)kcontrol->private_value) { + case H2_MIX_OUTPUT_ATT: + old = hal2_i_read32(hal2, H2I_DAC_C2); + new = old & ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE); + if (l | r) { + l = 31 - l; + r = 31 - r; + new |= (l << H2I_C2_L_ATT_SHIFT); + new |= (r << H2I_C2_R_ATT_SHIFT); + } else + new |= H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE; + hal2_i_write32(hal2, H2I_DAC_C2, new); + break; + case H2_MIX_INPUT_GAIN: + old = hal2_i_read32(hal2, H2I_ADC_C2); + new = old & ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M); + new |= (l << H2I_C2_L_GAIN_SHIFT); + new |= (r << H2I_C2_R_GAIN_SHIFT); + hal2_i_write32(hal2, H2I_ADC_C2, new); + break; + } + return old != new; +} + +static struct snd_kcontrol_new hal2_ctrl_headphone __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Headphone Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = H2_MIX_OUTPUT_ATT, + .info = hal2_gain_info, + .get = hal2_gain_get, + .put = hal2_gain_put, +}; + +static struct snd_kcontrol_new hal2_ctrl_mic __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Capture Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = H2_MIX_INPUT_GAIN, + .info = hal2_gain_info, + .get = hal2_gain_get, + .put = hal2_gain_put, +}; + +static int __devinit hal2_mixer_create(struct snd_hal2 *hal2) +{ + int err; + + /* mute DAC */ + hal2_i_write32(hal2, H2I_DAC_C2, + H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE); + /* mute ADC */ + hal2_i_write32(hal2, H2I_ADC_C2, 0); + + err = snd_ctl_add(hal2->card, + snd_ctl_new1(&hal2_ctrl_headphone, hal2)); + if (err < 0) + return err; + + err = snd_ctl_add(hal2->card, + snd_ctl_new1(&hal2_ctrl_mic, hal2)); + if (err < 0) + return err; + + return 0; +} + +static irqreturn_t hal2_interrupt(int irq, void *dev_id) +{ + struct snd_hal2 *hal2 = dev_id; + irqreturn_t ret = IRQ_NONE; + + /* decide what caused this interrupt */ + if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { + snd_pcm_period_elapsed(hal2->dac.substream); + ret = IRQ_HANDLED; + } + if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { + snd_pcm_period_elapsed(hal2->adc.substream); + ret = IRQ_HANDLED; + } + return ret; +} + +static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate) +{ + unsigned short mod; + + if (44100 % rate < 48000 % rate) { + mod = 4 * 44100 / rate; + codec->master = 44100; + } else { + mod = 4 * 48000 / rate; + codec->master = 48000; + } + + codec->inc = 4; + codec->mod = mod; + rate = 4 * codec->master / mod; + + return rate; +} + +static void hal2_set_dac_rate(struct snd_hal2 *hal2) +{ + unsigned int master = hal2->dac.master; + int inc = hal2->dac.inc; + int mod = hal2->dac.mod; + + hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0); + hal2_i_write32(hal2, H2I_BRES1_C2, + ((0xffff & (inc - mod - 1)) << 16) | inc); +} + +static void hal2_set_adc_rate(struct snd_hal2 *hal2) +{ + unsigned int master = hal2->adc.master; + int inc = hal2->adc.inc; + int mod = hal2->adc.mod; + + hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0); + hal2_i_write32(hal2, H2I_BRES2_C2, + ((0xffff & (inc - mod - 1)) << 16) | inc); +} + +static void hal2_setup_dac(struct snd_hal2 *hal2) +{ + unsigned int fifobeg, fifoend, highwater, sample_size; + struct hal2_pbus *pbus = &hal2->dac.pbus; + + /* Now we set up some PBUS information. The PBUS needs information about + * what portion of the fifo it will use. If it's receiving or + * transmitting, and finally whether the stream is little endian or big + * endian. The information is written later, on the start call. + */ + sample_size = 2 * hal2->dac.voices; + /* Fifo should be set to hold exactly four samples. Highwater mark + * should be set to two samples. */ + highwater = (sample_size * 2) >> 1; /* halfwords */ + fifobeg = 0; /* playback is first */ + fifoend = (sample_size * 4) >> 3; /* doublewords */ + pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD | + (highwater << 8) | (fifobeg << 16) | (fifoend << 24); + /* We disable everything before we do anything at all */ + pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; + hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); + /* Setup the HAL2 for playback */ + hal2_set_dac_rate(hal2); + /* Set endianess */ + hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); + /* Set DMA bus */ + hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); + /* We are using 1st Bresenham clock generator for playback */ + hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) + | (1 << H2I_C1_CLKID_SHIFT) + | (hal2->dac.voices << H2I_C1_DATAT_SHIFT)); +} + +static void hal2_setup_adc(struct snd_hal2 *hal2) +{ + unsigned int fifobeg, fifoend, highwater, sample_size; + struct hal2_pbus *pbus = &hal2->adc.pbus; + + sample_size = 2 * hal2->adc.voices; + highwater = (sample_size * 2) >> 1; /* halfwords */ + fifobeg = (4 * 4) >> 3; /* record is second */ + fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */ + pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | + (highwater << 8) | (fifobeg << 16) | (fifoend << 24); + pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; + hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); + /* Setup the HAL2 for record */ + hal2_set_adc_rate(hal2); + /* Set endianess */ + hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); + /* Set DMA bus */ + hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); + /* We are using 2nd Bresenham clock generator for record */ + hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) + | (2 << H2I_C1_CLKID_SHIFT) + | (hal2->adc.voices << H2I_C1_DATAT_SHIFT)); +} + +static void hal2_start_dac(struct snd_hal2 *hal2) +{ + struct hal2_pbus *pbus = &hal2->dac.pbus; + + pbus->pbus->pbdma_dptr = hal2->dac.desc_dma; + pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; + /* enable DAC */ + hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); +} + +static void hal2_start_adc(struct snd_hal2 *hal2) +{ + struct hal2_pbus *pbus = &hal2->adc.pbus; + + pbus->pbus->pbdma_dptr = hal2->adc.desc_dma; + pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; + /* enable ADC */ + hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); +} + +static inline void hal2_stop_dac(struct snd_hal2 *hal2) +{ + hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; + /* The HAL2 itself may remain enabled safely */ +} + +static inline void hal2_stop_adc(struct snd_hal2 *hal2) +{ + hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; +} + +static int hal2_alloc_dmabuf(struct hal2_codec *codec) +{ + struct hal2_desc *desc; + dma_addr_t desc_dma, buffer_dma; + int count = H2_BUF_SIZE / H2_BLOCK_SIZE; + int i; + + codec->buffer = dma_alloc_noncoherent(NULL, H2_BUF_SIZE, + &buffer_dma, GFP_KERNEL); + if (!codec->buffer) + return -ENOMEM; + desc = dma_alloc_noncoherent(NULL, count * sizeof(struct hal2_desc), + &desc_dma, GFP_KERNEL); + if (!desc) { + dma_free_noncoherent(NULL, H2_BUF_SIZE, + codec->buffer, buffer_dma); + return -ENOMEM; + } + codec->buffer_dma = buffer_dma; + codec->desc_dma = desc_dma; + codec->desc = desc; + for (i = 0; i < count; i++) { + desc->desc.pbuf = buffer_dma + i * H2_BLOCK_SIZE; + desc->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE; + desc->desc.pnext = (i == count - 1) ? + desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc); + desc++; + } + dma_cache_sync(NULL, codec->desc, count * sizeof(struct hal2_desc), + DMA_TO_DEVICE); + codec->desc_count = count; + return 0; +} + +static void hal2_free_dmabuf(struct hal2_codec *codec) +{ + dma_free_noncoherent(NULL, codec->desc_count * sizeof(struct hal2_desc), + codec->desc, codec->desc_dma); + dma_free_noncoherent(NULL, H2_BUF_SIZE, codec->buffer, + codec->buffer_dma); +} + +static struct snd_pcm_hardware hal2_pcm_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER), + .formats = SNDRV_PCM_FMTBIT_S16_BE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 65536, + .period_bytes_min = 1024, + .period_bytes_max = 65536, + .periods_min = 2, + .periods_max = 1024, +}; + +static int hal2_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + int err; + + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + if (err < 0) + return err; + + return 0; +} + +static int hal2_pcm_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +static int hal2_playback_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + int err; + + runtime->hw = hal2_pcm_hw; + + err = hal2_alloc_dmabuf(&hal2->dac); + if (err) + return err; + return 0; +} + +static int hal2_playback_close(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + + hal2_free_dmabuf(&hal2->dac); + return 0; +} + +static int hal2_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct hal2_codec *dac = &hal2->dac; + + dac->voices = runtime->channels; + dac->sample_rate = hal2_compute_rate(dac, runtime->rate); + memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect)); + dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; + dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); + dac->substream = substream; + hal2_setup_dac(hal2); + return 0; +} + +static int hal2_playback_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + hal2->dac.pcm_indirect.hw_io = hal2->dac.buffer_dma; + hal2->dac.pcm_indirect.hw_data = 0; + substream->ops->ack(substream); + hal2_start_dac(hal2); + break; + case SNDRV_PCM_TRIGGER_STOP: + hal2_stop_dac(hal2); + break; + default: + return -EINVAL; + } + return 0; +} + +static snd_pcm_uframes_t +hal2_playback_pointer(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct hal2_codec *dac = &hal2->dac; + + return snd_pcm_indirect_playback_pointer(substream, &dac->pcm_indirect, + dac->pbus.pbus->pbdma_bptr); +} + +static void hal2_playback_transfer(struct snd_pcm_substream *substream, + struct snd_pcm_indirect *rec, size_t bytes) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + unsigned char *buf = hal2->dac.buffer + rec->hw_data; + + memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes); + dma_cache_sync(NULL, buf, bytes, DMA_TO_DEVICE); + +} + +static int hal2_playback_ack(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct hal2_codec *dac = &hal2->dac; + + dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; + snd_pcm_indirect_playback_transfer(substream, + &dac->pcm_indirect, + hal2_playback_transfer); + return 0; +} + +static int hal2_capture_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct hal2_codec *adc = &hal2->adc; + int err; + + runtime->hw = hal2_pcm_hw; + + err = hal2_alloc_dmabuf(adc); + if (err) + return err; + return 0; +} + +static int hal2_capture_close(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + + hal2_free_dmabuf(&hal2->adc); + return 0; +} + +static int hal2_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct hal2_codec *adc = &hal2->adc; + + adc->voices = runtime->channels; + adc->sample_rate = hal2_compute_rate(adc, runtime->rate); + memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect)); + adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; + adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; + adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); + adc->substream = substream; + hal2_setup_adc(hal2); + return 0; +} + +static int hal2_capture_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + hal2->adc.pcm_indirect.hw_io = hal2->adc.buffer_dma; + hal2->adc.pcm_indirect.hw_data = 0; + printk(KERN_DEBUG "buffer_dma %x\n", hal2->adc.buffer_dma); + hal2_start_adc(hal2); + break; + case SNDRV_PCM_TRIGGER_STOP: + hal2_stop_adc(hal2); + break; + default: + return -EINVAL; + } + return 0; +} + +static snd_pcm_uframes_t +hal2_capture_pointer(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct hal2_codec *adc = &hal2->adc; + + return snd_pcm_indirect_capture_pointer(substream, &adc->pcm_indirect, + adc->pbus.pbus->pbdma_bptr); +} + +static void hal2_capture_transfer(struct snd_pcm_substream *substream, + struct snd_pcm_indirect *rec, size_t bytes) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + unsigned char *buf = hal2->adc.buffer + rec->hw_data; + + dma_cache_sync(NULL, buf, bytes, DMA_FROM_DEVICE); + memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes); +} + +static int hal2_capture_ack(struct snd_pcm_substream *substream) +{ + struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); + struct hal2_codec *adc = &hal2->adc; + + snd_pcm_indirect_capture_transfer(substream, + &adc->pcm_indirect, + hal2_capture_transfer); + return 0; +} + +static struct snd_pcm_ops hal2_playback_ops = { + .open = hal2_playback_open, + .close = hal2_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = hal2_pcm_hw_params, + .hw_free = hal2_pcm_hw_free, + .prepare = hal2_playback_prepare, + .trigger = hal2_playback_trigger, + .pointer = hal2_playback_pointer, + .ack = hal2_playback_ack, +}; + +static struct snd_pcm_ops hal2_capture_ops = { + .open = hal2_capture_open, + .close = hal2_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = hal2_pcm_hw_params, + .hw_free = hal2_pcm_hw_free, + .prepare = hal2_capture_prepare, + .trigger = hal2_capture_trigger, + .pointer = hal2_capture_pointer, + .ack = hal2_capture_ack, +}; + +static int __devinit hal2_pcm_create(struct snd_hal2 *hal2) +{ + struct snd_pcm *pcm; + int err; + + /* create first pcm device with one outputs and one input */ + err = snd_pcm_new(hal2->card, "SGI HAL2 Audio", 0, 1, 1, &pcm); + if (err < 0) + return err; + + pcm->private_data = hal2; + strcpy(pcm->name, "SGI HAL2"); + + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &hal2_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &hal2_capture_ops); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + 0, 1024 * 1024); + + return 0; +} + +static int hal2_dev_free(struct snd_device *device) +{ + struct snd_hal2 *hal2 = device->device_data; + + free_irq(SGI_HPCDMA_IRQ, hal2); + kfree(hal2); + return 0; +} + +static struct snd_device_ops hal2_ops = { + .dev_free = hal2_dev_free, +}; + +static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3, + int index) +{ + codec->pbus.pbusnr = index; + codec->pbus.pbus = &hpc3->pbdma[index]; +} + +static int hal2_detect(struct snd_hal2 *hal2) +{ + unsigned short board, major, minor; + unsigned short rev; + + /* reset HAL2 */ + hal2_write(0, &hal2->ctl_regs->isr); + + /* release reset */ + hal2_write(H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N, + &hal2->ctl_regs->isr); + + + hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); + rev = hal2_read(&hal2->ctl_regs->rev); + if (rev & H2_REV_AUDIO_PRESENT) + return -ENODEV; + + board = (rev & H2_REV_BOARD_M) >> 12; + major = (rev & H2_REV_MAJOR_CHIP_M) >> 4; + minor = (rev & H2_REV_MINOR_CHIP_M); + + printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n", + board, major, minor); + + return 0; +} + +static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip) +{ + struct snd_hal2 *hal2; + struct hpc3_regs *hpc3 = hpc3c0; + int err; + + hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL); + if (!hal2) + return -ENOMEM; + + hal2->card = card; + + if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED, + "SGI HAL2", hal2)) { + printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ); + kfree(hal2); + return -EAGAIN; + } + + hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0]; + hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1]; + hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2]; + hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3]; + + if (hal2_detect(hal2) < 0) { + kfree(hal2); + return -ENODEV; + } + + hal2_init_codec(&hal2->dac, hpc3, 0); + hal2_init_codec(&hal2->adc, hpc3, 1); + + /* + * All DMA channel interfaces in HAL2 are designed to operate with + * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles + * in D5. HAL2 is a 16-bit device which can accept both big and little + * endian format. It assumes that even address bytes are on high + * portion of PBUS (15:8) and assumes that HPC3 is programmed to + * accept a live (unsynchronized) version of P_DREQ_N from HAL2. + */ +#define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \ + (2 << HPC3_DMACFG_D4R_SHIFT) | \ + (2 << HPC3_DMACFG_D5R_SHIFT) | \ + (0 << HPC3_DMACFG_D3W_SHIFT) | \ + (2 << HPC3_DMACFG_D4W_SHIFT) | \ + (2 << HPC3_DMACFG_D5W_SHIFT) | \ + HPC3_DMACFG_DS16 | \ + HPC3_DMACFG_EVENHI | \ + HPC3_DMACFG_RTIME | \ + (8 << HPC3_DMACFG_BURST_SHIFT) | \ + HPC3_DMACFG_DRQLIVE) + /* + * Ignore what's mentioned in the specification and write value which + * works in The Real World (TM) + */ + hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844; + hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844; + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hal2, &hal2_ops); + if (err < 0) { + free_irq(SGI_HPCDMA_IRQ, hal2); + kfree(hal2); + return err; + } + *rchip = hal2; + return 0; +} + +static int __devinit hal2_probe(struct platform_device *pdev) +{ + struct snd_card *card; + struct snd_hal2 *chip; + int err; + + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + err = hal2_create(card, &chip); + if (err < 0) { + snd_card_free(card); + return err; + } + snd_card_set_dev(card, &pdev->dev); + + err = hal2_pcm_create(chip); + if (err < 0) { + snd_card_free(card); + return err; + } + err = hal2_mixer_create(chip); + if (err < 0) { + snd_card_free(card); + return err; + } + + strcpy(card->driver, "SGI HAL2 Audio"); + strcpy(card->shortname, "SGI HAL2 Audio"); + sprintf(card->longname, "%s irq %i", + card->shortname, + SGI_HPCDMA_IRQ); + + err = snd_card_register(card); + if (err < 0) { + snd_card_free(card); + return err; + } + platform_set_drvdata(pdev, card); + return 0; +} + +static int __exit hal2_remove(struct platform_device *pdev) +{ + struct snd_card *card = platform_get_drvdata(pdev); + + snd_card_free(card); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver hal2_driver = { + .probe = hal2_probe, + .remove = __devexit_p(hal2_remove), + .driver = { + .name = "sgihal2", + .owner = THIS_MODULE, + } +}; + +static int __init alsa_card_hal2_init(void) +{ + return platform_driver_register(&hal2_driver); +} + +static void __exit alsa_card_hal2_exit(void) +{ + platform_driver_unregister(&hal2_driver); +} + +module_init(alsa_card_hal2_init); +module_exit(alsa_card_hal2_exit); diff --git a/sound/mips/hal2.h b/sound/mips/hal2.h new file mode 100644 index 00000000000..f19828bc64e --- /dev/null +++ b/sound/mips/hal2.h @@ -0,0 +1,245 @@ +#ifndef __HAL2_H +#define __HAL2_H + +/* + * Driver for HAL2 sound processors + * Copyright (c) 1999 Ulf Carlsson + * Copyright (c) 2001, 2002, 2003 Ladislav Michl + * + * 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. + * + */ + +#include + +/* Indirect status register */ + +#define H2_ISR_TSTATUS 0x01 /* RO: transaction status 1=busy */ +#define H2_ISR_USTATUS 0x02 /* RO: utime status bit 1=armed */ +#define H2_ISR_QUAD_MODE 0x04 /* codec mode 0=indigo 1=quad */ +#define H2_ISR_GLOBAL_RESET_N 0x08 /* chip global reset 0=reset */ +#define H2_ISR_CODEC_RESET_N 0x10 /* codec/synth reset 0=reset */ + +/* Revision register */ + +#define H2_REV_AUDIO_PRESENT 0x8000 /* RO: audio present 0=present */ +#define H2_REV_BOARD_M 0x7000 /* RO: bits 14:12, board revision */ +#define H2_REV_MAJOR_CHIP_M 0x00F0 /* RO: bits 7:4, major chip revision */ +#define H2_REV_MINOR_CHIP_M 0x000F /* RO: bits 3:0, minor chip revision */ + +/* Indirect address register */ + +/* + * Address of indirect internal register to be accessed. A write to this + * register initiates read or write access to the indirect registers in the + * HAL2. Note that there af four indirect data registers for write access to + * registers larger than 16 byte. + */ + +#define H2_IAR_TYPE_M 0xF000 /* bits 15:12, type of functional */ + /* block the register resides in */ + /* 1=DMA Port */ + /* 9=Global DMA Control */ + /* 2=Bresenham */ + /* 3=Unix Timer */ +#define H2_IAR_NUM_M 0x0F00 /* bits 11:8 instance of the */ + /* blockin which the indirect */ + /* register resides */ + /* If IAR_TYPE_M=DMA Port: */ + /* 1=Synth In */ + /* 2=AES In */ + /* 3=AES Out */ + /* 4=DAC Out */ + /* 5=ADC Out */ + /* 6=Synth Control */ + /* If IAR_TYPE_M=Global DMA Control: */ + /* 1=Control */ + /* If IAR_TYPE_M=Bresenham: */ + /* 1=Bresenham Clock Gen 1 */ + /* 2=Bresenham Clock Gen 2 */ + /* 3=Bresenham Clock Gen 3 */ + /* If IAR_TYPE_M=Unix Timer: */ + /* 1=Unix Timer */ +#define H2_IAR_ACCESS_SELECT 0x0080 /* 1=read 0=write */ +#define H2_IAR_PARAM 0x000C /* Parameter Select */ +#define H2_IAR_RB_INDEX_M 0x0003 /* Read Back Index */ + /* 00:word0 */ + /* 01:word1 */ + /* 10:word2 */ + /* 11:word3 */ +/* + * HAL2 internal addressing + * + * The HAL2 has "indirect registers" (idr) which are accessed by writing to the + * Indirect Data registers. Write the address to the Indirect Address register + * to transfer the data. + * + * We define the H2IR_* to the read address and H2IW_* to the write address and + * H2I_* to be fields in whatever register is referred to. + * + * When we write to indirect registers which are larger than one word (16 bit) + * we have to fill more than one indirect register before writing. When we read + * back however we have to read several times, each time with different Read + * Back Indexes (there are defs for doing this easily). + */ + +/* + * Relay Control + */ +#define H2I_RELAY_C 0x9100 +#define H2I_RELAY_C_STATE 0x01 /* state of RELAY pin signal */ + +/* DMA port enable */ + +#define H2I_DMA_PORT_EN 0x9104 +#define H2I_DMA_PORT_EN_SY_IN 0x01 /* Synth_in DMA port */ +#define H2I_DMA_PORT_EN_AESRX 0x02 /* AES receiver DMA port */ +#define H2I_DMA_PORT_EN_AESTX 0x04 /* AES transmitter DMA port */ +#define H2I_DMA_PORT_EN_CODECTX 0x08 /* CODEC transmit DMA port */ +#define H2I_DMA_PORT_EN_CODECR 0x10 /* CODEC receive DMA port */ + +#define H2I_DMA_END 0x9108 /* global dma endian select */ +#define H2I_DMA_END_SY_IN 0x01 /* Synth_in DMA port */ +#define H2I_DMA_END_AESRX 0x02 /* AES receiver DMA port */ +#define H2I_DMA_END_AESTX 0x04 /* AES transmitter DMA port */ +#define H2I_DMA_END_CODECTX 0x08 /* CODEC transmit DMA port */ +#define H2I_DMA_END_CODECR 0x10 /* CODEC receive DMA port */ + /* 0=b_end 1=l_end */ + +#define H2I_DMA_DRV 0x910C /* global PBUS DMA enable */ + +#define H2I_SYNTH_C 0x1104 /* Synth DMA control */ + +#define H2I_AESRX_C 0x1204 /* AES RX dma control */ + +#define H2I_C_TS_EN 0x20 /* Timestamp enable */ +#define H2I_C_TS_FRMT 0x40 /* Timestamp format */ +#define H2I_C_NAUDIO 0x80 /* Sign extend */ + +/* AESRX CTL, 16 bit */ + +#define H2I_AESTX_C 0x1304 /* AES TX DMA control */ +#define H2I_AESTX_C_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */ +#define H2I_AESTX_C_CLKID_M 0x18 +#define H2I_AESTX_C_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */ +#define H2I_AESTX_C_DATAT_M 0x300 + +/* CODEC registers */ + +#define H2I_DAC_C1 0x1404 /* DAC DMA control, 16 bit */ +#define H2I_DAC_C2 0x1408 /* DAC DMA control, 32 bit */ +#define H2I_ADC_C1 0x1504 /* ADC DMA control, 16 bit */ +#define H2I_ADC_C2 0x1508 /* ADC DMA control, 32 bit */ + +/* Bits in CTL1 register */ + +#define H2I_C1_DMA_SHIFT 0 /* DMA channel */ +#define H2I_C1_DMA_M 0x7 +#define H2I_C1_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */ +#define H2I_C1_CLKID_M 0x18 +#define H2I_C1_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */ +#define H2I_C1_DATAT_M 0x300 + +/* Bits in CTL2 register */ + +#define H2I_C2_R_GAIN_SHIFT 0 /* right a/d input gain */ +#define H2I_C2_R_GAIN_M 0xf +#define H2I_C2_L_GAIN_SHIFT 4 /* left a/d input gain */ +#define H2I_C2_L_GAIN_M 0xf0 +#define H2I_C2_R_SEL 0x100 /* right input select */ +#define H2I_C2_L_SEL 0x200 /* left input select */ +#define H2I_C2_MUTE 0x400 /* mute */ +#define H2I_C2_DO1 0x00010000 /* digital output port bit 0 */ +#define H2I_C2_DO2 0x00020000 /* digital output port bit 1 */ +#define H2I_C2_R_ATT_SHIFT 18 /* right d/a output - */ +#define H2I_C2_R_ATT_M 0x007c0000 /* attenuation */ +#define H2I_C2_L_ATT_SHIFT 23 /* left d/a output - */ +#define H2I_C2_L_ATT_M 0x0f800000 /* attenuation */ + +#define H2I_SYNTH_MAP_C 0x1104 /* synth dma handshake ctrl */ + +/* Clock generator CTL 1, 16 bit */ + +#define H2I_BRES1_C1 0x2104 +#define H2I_BRES2_C1 0x2204 +#define H2I_BRES3_C1 0x2304 + +#define H2I_BRES_C1_SHIFT 0 /* 0=48.0 1=44.1 2=aes_rx */ +#define H2I_BRES_C1_M 0x03 + +/* Clock generator CTL 2, 32 bit */ + +#define H2I_BRES1_C2 0x2108 +#define H2I_BRES2_C2 0x2208 +#define H2I_BRES3_C2 0x2308 + +#define H2I_BRES_C2_INC_SHIFT 0 /* increment value */ +#define H2I_BRES_C2_INC_M 0xffff +#define H2I_BRES_C2_MOD_SHIFT 16 /* modcontrol value */ +#define H2I_BRES_C2_MOD_M 0xffff0000 /* modctrl=0xffff&(modinc-1) */ + +/* Unix timer, 64 bit */ + +#define H2I_UTIME 0x3104 +#define H2I_UTIME_0_LD 0xffff /* microseconds, LSB's */ +#define H2I_UTIME_1_LD0 0x0f /* microseconds, MSB's */ +#define H2I_UTIME_1_LD1 0xf0 /* tenths of microseconds */ +#define H2I_UTIME_2_LD 0xffff /* seconds, LSB's */ +#define H2I_UTIME_3_LD 0xffff /* seconds, MSB's */ + +struct hal2_ctl_regs { + u32 _unused0[4]; + u32 isr; /* 0x10 Status Register */ + u32 _unused1[3]; + u32 rev; /* 0x20 Revision Register */ + u32 _unused2[3]; + u32 iar; /* 0x30 Indirect Address Register */ + u32 _unused3[3]; + u32 idr0; /* 0x40 Indirect Data Register 0 */ + u32 _unused4[3]; + u32 idr1; /* 0x50 Indirect Data Register 1 */ + u32 _unused5[3]; + u32 idr2; /* 0x60 Indirect Data Register 2 */ + u32 _unused6[3]; + u32 idr3; /* 0x70 Indirect Data Register 3 */ +}; + +struct hal2_aes_regs { + u32 rx_stat[2]; /* Status registers */ + u32 rx_cr[2]; /* Control registers */ + u32 rx_ud[4]; /* User data window */ + u32 rx_st[24]; /* Channel status data */ + + u32 tx_stat[1]; /* Status register */ + u32 tx_cr[3]; /* Control registers */ + u32 tx_ud[4]; /* User data window */ + u32 tx_st[24]; /* Channel status data */ +}; + +struct hal2_vol_regs { + u32 right; /* Right volume */ + u32 left; /* Left volume */ +}; + +struct hal2_syn_regs { + u32 _unused0[2]; + u32 page; /* DOC Page register */ + u32 regsel; /* DOC Register selection */ + u32 dlow; /* DOC Data low */ + u32 dhigh; /* DOC Data high */ + u32 irq; /* IRQ Status */ + u32 dram; /* DRAM Access */ +}; + +#endif /* __HAL2_H */ -- GitLab From 1e066322c26562621811effb1eb14097bc67a9ee Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 11 Jul 2008 14:05:17 +0100 Subject: [PATCH 1735/2509] ALSA: asoc: kbuild - only show menus for the current ASoC CPU platform. We don't want to see ASoC platform menus for other non selected architectures in our config. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/soc/fsl/Kconfig | 4 ---- sound/soc/omap/Kconfig | 4 ---- 2 files changed, 8 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 19802e27df4..3368ace6097 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,5 +1,3 @@ -menu "ALSA SoC audio for Freescale SOCs" - config SND_SOC_MPC8610 bool "ALSA SoC support for the MPC8610 SOC" depends on MPC8610_HPCD @@ -16,5 +14,3 @@ config SND_SOC_MPC8610_HPCD default y if MPC8610_HPCD help Say Y if you want to enable audio on the Freescale MPC8610 HPCD. - -endmenu diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 0230d83e8e5..aea27e70043 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Texas Instruments OMAP" - config SND_OMAP_SOC tristate "SoC Audio for the Texas Instruments OMAP chips" depends on ARCH_OMAP && SND_SOC @@ -15,5 +13,3 @@ config SND_OMAP_SOC_N810 select SND_SOC_TLV320AIC3X help Say Y if you want to add support for SoC audio on Nokia N810. - -endmenu -- GitLab From 862c2c0a61c515f2e9f63f689215bcf99a607eaf Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 12 Jul 2008 22:43:50 +0200 Subject: [PATCH 1736/2509] ALSA: ALSA driver for SGI O2 audio board This patch adds a new ALSA driver for the audio device found inside most of the SGI O2 workstation. The hardware uses a SGI custom chip, which feeds a AD codec chip. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- include/sound/ad1843.h | 46 ++ sound/mips/Kconfig | 6 + sound/mips/Makefile | 2 + sound/mips/ad1843.c | 561 ++++++++++++++++++++++ sound/mips/sgio2audio.c | 1006 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 1621 insertions(+) create mode 100644 include/sound/ad1843.h create mode 100644 sound/mips/ad1843.c create mode 100644 sound/mips/sgio2audio.c diff --git a/include/sound/ad1843.h b/include/sound/ad1843.h new file mode 100644 index 00000000000..b236a9d1d6e --- /dev/null +++ b/include/sound/ad1843.h @@ -0,0 +1,46 @@ +/* + * 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 2003 Vivien Chappelier + * Copyright 2008 Thomas Bogendoerfer + */ + +#ifndef __SOUND_AD1843_H +#define __SOUND_AD1843_H + +struct snd_ad1843 { + void *chip; + int (*read)(void *chip, int reg); + int (*write)(void *chip, int reg, int val); +}; + +#define AD1843_GAIN_RECLEV 0 +#define AD1843_GAIN_LINE 1 +#define AD1843_GAIN_LINE_2 2 +#define AD1843_GAIN_MIC 3 +#define AD1843_GAIN_PCM_0 4 +#define AD1843_GAIN_PCM_1 5 +#define AD1843_GAIN_SIZE (AD1843_GAIN_PCM_1+1) + +int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id); +int ad1843_get_gain(struct snd_ad1843 *ad1843, int id); +int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval); +int ad1843_get_recsrc(struct snd_ad1843 *ad1843); +int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc); +void ad1843_setup_dac(struct snd_ad1843 *ad1843, + unsigned int id, + unsigned int framerate, + snd_pcm_format_t fmt, + unsigned int channels); +void ad1843_shutdown_dac(struct snd_ad1843 *ad1843, + unsigned int id); +void ad1843_setup_adc(struct snd_ad1843 *ad1843, + unsigned int framerate, + snd_pcm_format_t fmt, + unsigned int channels); +void ad1843_shutdown_adc(struct snd_ad1843 *ad1843); +int ad1843_init(struct snd_ad1843 *ad1843); + +#endif /* __SOUND_AD1843_H */ diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index 2a61cade4ac..a9823fad85c 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -9,6 +9,12 @@ menuconfig SND_MIPS if SND_MIPS +config SND_SGI_O2 + tristate "SGI O2 Audio" + depends on SGI_IP32 + help + Sound support for the SGI O2 Workstation. + config SND_SGI_HAL2 tristate "SGI HAL2 Audio" depends on SGI_HAS_HAL2 diff --git a/sound/mips/Makefile b/sound/mips/Makefile index 63f4a9c0a8d..861ec0a574b 100644 --- a/sound/mips/Makefile +++ b/sound/mips/Makefile @@ -3,8 +3,10 @@ # snd-au1x00-objs := au1x00.o +snd-sgi-o2-objs := sgio2audio.o ad1843.o snd-sgi-hal2-objs := hal2.o # Toplevel Module Dependency obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o +obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o diff --git a/sound/mips/ad1843.c b/sound/mips/ad1843.c new file mode 100644 index 00000000000..c624510ec37 --- /dev/null +++ b/sound/mips/ad1843.c @@ -0,0 +1,561 @@ +/* + * AD1843 low level driver + * + * Copyright 2003 Vivien Chappelier + * Copyright 2008 Thomas Bogendoerfer + * + * inspired from vwsnd.c (SGI VW audio driver) + * Copyright 1999 Silicon Graphics, 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 + +/* + * AD1843 bitfield definitions. All are named as in the AD1843 data + * sheet, with ad1843_ prepended and individual bit numbers removed. + * + * E.g., bits LSS0 through LSS2 become ad1843_LSS. + * + * Only the bitfields we need are defined. + */ + +struct ad1843_bitfield { + char reg; + char lo_bit; + char nbits; +}; + +static const struct ad1843_bitfield + ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */ + ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */ + ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */ + ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */ + ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */ + ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */ + ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */ + ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */ + ad1843_RD2M = { 3, 0, 5 }, /* Right DAC 2 Mix Gain/Atten */ + ad1843_RD2MM = { 3, 7, 1 }, /* Right DAC 2 Mix Mute */ + ad1843_LD2M = { 3, 8, 5 }, /* Left DAC 2 Mix Gain/Atten */ + ad1843_LD2MM = { 3, 15, 1 }, /* Left DAC 2 Mix Mute */ + ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */ + ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */ + ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */ + ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */ + ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */ + ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */ + ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */ + ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */ + ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */ + ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */ + ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */ + ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */ + ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */ + ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */ + ad1843_MPOM = { 8, 6, 1 }, /* Mono Output Mute */ + ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */ + ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */ + ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */ + ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */ + ad1843_RDA2G = { 10, 0, 6 }, /* Right DAC2 Analog/Digital Gain */ + ad1843_RDA2GM = { 10, 7, 1 }, /* Right DAC2 Analog Mute */ + ad1843_LDA2G = { 10, 8, 6 }, /* Left DAC2 Analog/Digital Gain */ + ad1843_LDA2GM = { 10, 15, 1 }, /* Left DAC2 Analog Mute */ + ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */ + ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */ + ad1843_RDA2AM = { 12, 7, 1 }, /* Right DAC2 Digital Mute */ + ad1843_LDA2AM = { 12, 15, 1 }, /* Left DAC2 Digital Mute */ + ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */ + ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */ + ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */ + ad1843_DA2C = { 15, 10, 2 }, /* DAC2 Sample Rate Source */ + ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */ + ad1843_C2C = { 20, 0, 16 }, /* Clock 2 Sample Rate Select */ + ad1843_C3C = { 23, 0, 16 }, /* Clock 3 Sample Rate Select */ + ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */ + ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */ + ad1843_DAMIX = { 25, 14, 1 }, /* DAC Digital Mix Enable */ + ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */ + ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */ + ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */ + ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */ + ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */ + ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */ + ad1843_DA2F = { 26, 10, 2 }, /* DAC2 Data Format Select */ + ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */ + ad1843_DA2SM = { 26, 15, 1 }, /* DAC2 Stereo/Mono Mode Select */ + ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */ + ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */ + ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */ + ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */ + ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */ + ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */ + ad1843_DDMEN = { 27, 12, 1 }, /* DAC2 to DAC1 Mix Enable */ + ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */ + ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */ + ad1843_C3EN = { 28, 13, 1 }, /* Clock Generator 3 Enable */ + ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */ + +/* + * The various registers of the AD1843 use three different formats for + * specifying gain. The ad1843_gain structure parameterizes the + * formats. + */ + +struct ad1843_gain { + int negative; /* nonzero if gain is negative. */ + const struct ad1843_bitfield *lfield; + const struct ad1843_bitfield *rfield; + const struct ad1843_bitfield *lmute; + const struct ad1843_bitfield *rmute; +}; + +static const struct ad1843_gain ad1843_gain_RECLEV = { + .negative = 0, + .lfield = &ad1843_LIG, + .rfield = &ad1843_RIG +}; +static const struct ad1843_gain ad1843_gain_LINE = { + .negative = 1, + .lfield = &ad1843_LX1M, + .rfield = &ad1843_RX1M, + .lmute = &ad1843_LX1MM, + .rmute = &ad1843_RX1MM +}; +static const struct ad1843_gain ad1843_gain_LINE_2 = { + .negative = 1, + .lfield = &ad1843_LDA2G, + .rfield = &ad1843_RDA2G, + .lmute = &ad1843_LDA2GM, + .rmute = &ad1843_RDA2GM +}; +static const struct ad1843_gain ad1843_gain_MIC = { + .negative = 1, + .lfield = &ad1843_LMCM, + .rfield = &ad1843_RMCM, + .lmute = &ad1843_LMCMM, + .rmute = &ad1843_RMCMM +}; +static const struct ad1843_gain ad1843_gain_PCM_0 = { + .negative = 1, + .lfield = &ad1843_LDA1G, + .rfield = &ad1843_RDA1G, + .lmute = &ad1843_LDA1GM, + .rmute = &ad1843_RDA1GM +}; +static const struct ad1843_gain ad1843_gain_PCM_1 = { + .negative = 1, + .lfield = &ad1843_LD2M, + .rfield = &ad1843_RD2M, + .lmute = &ad1843_LD2MM, + .rmute = &ad1843_RD2MM +}; + +static const struct ad1843_gain *ad1843_gain[AD1843_GAIN_SIZE] = +{ + &ad1843_gain_RECLEV, + &ad1843_gain_LINE, + &ad1843_gain_LINE_2, + &ad1843_gain_MIC, + &ad1843_gain_PCM_0, + &ad1843_gain_PCM_1, +}; + +/* read the current value of an AD1843 bitfield. */ + +static int ad1843_read_bits(struct snd_ad1843 *ad1843, + const struct ad1843_bitfield *field) +{ + int w; + + w = ad1843->read(ad1843->chip, field->reg); + return w >> field->lo_bit & ((1 << field->nbits) - 1); +} + +/* + * write a new value to an AD1843 bitfield and return the old value. + */ + +static int ad1843_write_bits(struct snd_ad1843 *ad1843, + const struct ad1843_bitfield *field, + int newval) +{ + int w, mask, oldval, newbits; + + w = ad1843->read(ad1843->chip, field->reg); + mask = ((1 << field->nbits) - 1) << field->lo_bit; + oldval = (w & mask) >> field->lo_bit; + newbits = (newval << field->lo_bit) & mask; + w = (w & ~mask) | newbits; + ad1843->write(ad1843->chip, field->reg, w); + + return oldval; +} + +/* + * ad1843_read_multi reads multiple bitfields from the same AD1843 + * register. It uses a single read cycle to do it. (Reading the + * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20 + * microseconds.) + * + * Called like this. + * + * ad1843_read_multi(ad1843, nfields, + * &ad1843_FIELD1, &val1, + * &ad1843_FIELD2, &val2, ...); + */ + +static void ad1843_read_multi(struct snd_ad1843 *ad1843, int argcount, ...) +{ + va_list ap; + const struct ad1843_bitfield *fp; + int w = 0, mask, *value, reg = -1; + + va_start(ap, argcount); + while (--argcount >= 0) { + fp = va_arg(ap, const struct ad1843_bitfield *); + value = va_arg(ap, int *); + if (reg == -1) { + reg = fp->reg; + w = ad1843->read(ad1843->chip, reg); + } + + mask = (1 << fp->nbits) - 1; + *value = w >> fp->lo_bit & mask; + } + va_end(ap); +} + +/* + * ad1843_write_multi stores multiple bitfields into the same AD1843 + * register. It uses one read and one write cycle to do it. + * + * Called like this. + * + * ad1843_write_multi(ad1843, nfields, + * &ad1843_FIELD1, val1, + * &ad1843_FIELF2, val2, ...); + */ + +static void ad1843_write_multi(struct snd_ad1843 *ad1843, int argcount, ...) +{ + va_list ap; + int reg; + const struct ad1843_bitfield *fp; + int value; + int w, m, mask, bits; + + mask = 0; + bits = 0; + reg = -1; + + va_start(ap, argcount); + while (--argcount >= 0) { + fp = va_arg(ap, const struct ad1843_bitfield *); + value = va_arg(ap, int); + if (reg == -1) + reg = fp->reg; + else + BUG_ON(reg != fp->reg); + m = ((1 << fp->nbits) - 1) << fp->lo_bit; + mask |= m; + bits |= (value << fp->lo_bit) & m; + } + va_end(ap); + + if (~mask & 0xFFFF) + w = ad1843->read(ad1843->chip, reg); + else + w = 0; + w = (w & ~mask) | bits; + ad1843->write(ad1843->chip, reg, w); +} + +int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id) +{ + const struct ad1843_gain *gp = ad1843_gain[id]; + int ret; + + ret = (1 << gp->lfield->nbits); + if (!gp->lmute) + ret -= 1; + return ret; +} + +/* + * ad1843_get_gain reads the specified register and extracts the gain value + * using the supplied gain type. + */ + +int ad1843_get_gain(struct snd_ad1843 *ad1843, int id) +{ + int lg, rg, lm, rm; + const struct ad1843_gain *gp = ad1843_gain[id]; + unsigned short mask = (1 << gp->lfield->nbits) - 1; + + ad1843_read_multi(ad1843, 2, gp->lfield, &lg, gp->rfield, &rg); + if (gp->negative) { + lg = mask - lg; + rg = mask - rg; + } + if (gp->lmute) { + ad1843_read_multi(ad1843, 2, gp->lmute, &lm, gp->rmute, &rm); + if (lm) + lg = 0; + if (rm) + rg = 0; + } + return lg << 0 | rg << 8; +} + +/* + * Set an audio channel's gain. + * + * Returns the new gain, which may be lower than the old gain. + */ + +int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval) +{ + const struct ad1843_gain *gp = ad1843_gain[id]; + unsigned short mask = (1 << gp->lfield->nbits) - 1; + + int lg = (newval >> 0) & mask; + int rg = (newval >> 8) & mask; + int lm = (lg == 0) ? 1 : 0; + int rm = (rg == 0) ? 1 : 0; + + if (gp->negative) { + lg = mask - lg; + rg = mask - rg; + } + if (gp->lmute) + ad1843_write_multi(ad1843, 2, gp->lmute, lm, gp->rmute, rm); + ad1843_write_multi(ad1843, 2, gp->lfield, lg, gp->rfield, rg); + return ad1843_get_gain(ad1843, id); +} + +/* Returns the current recording source */ + +int ad1843_get_recsrc(struct snd_ad1843 *ad1843) +{ + int val = ad1843_read_bits(ad1843, &ad1843_LSS); + + if (val < 0 || val > 2) { + val = 2; + ad1843_write_multi(ad1843, 2, + &ad1843_LSS, val, &ad1843_RSS, val); + } + return val; +} + +/* + * Set recording source. + * + * Returns newsrc on success, -errno on failure. + */ + +int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc) +{ + if (newsrc < 0 || newsrc > 2) + return -EINVAL; + + ad1843_write_multi(ad1843, 2, &ad1843_LSS, newsrc, &ad1843_RSS, newsrc); + return newsrc; +} + +/* Setup ad1843 for D/A conversion. */ + +void ad1843_setup_dac(struct snd_ad1843 *ad1843, + unsigned int id, + unsigned int framerate, + snd_pcm_format_t fmt, + unsigned int channels) +{ + int ad_fmt = 0, ad_mode = 0; + + switch (fmt) { + case SNDRV_PCM_FORMAT_S8: + ad_fmt = 0; + break; + case SNDRV_PCM_FORMAT_U8: + ad_fmt = 0; + break; + case SNDRV_PCM_FORMAT_S16_LE: + ad_fmt = 1; + break; + case SNDRV_PCM_FORMAT_MU_LAW: + ad_fmt = 2; + break; + case SNDRV_PCM_FORMAT_A_LAW: + ad_fmt = 3; + break; + default: + break; + } + + switch (channels) { + case 2: + ad_mode = 0; + break; + case 1: + ad_mode = 1; + break; + default: + break; + } + + if (id) { + ad1843_write_bits(ad1843, &ad1843_C2C, framerate); + ad1843_write_multi(ad1843, 2, + &ad1843_DA2SM, ad_mode, + &ad1843_DA2F, ad_fmt); + } else { + ad1843_write_bits(ad1843, &ad1843_C1C, framerate); + ad1843_write_multi(ad1843, 2, + &ad1843_DA1SM, ad_mode, + &ad1843_DA1F, ad_fmt); + } +} + +void ad1843_shutdown_dac(struct snd_ad1843 *ad1843, unsigned int id) +{ + if (id) + ad1843_write_bits(ad1843, &ad1843_DA2F, 1); + else + ad1843_write_bits(ad1843, &ad1843_DA1F, 1); +} + +void ad1843_setup_adc(struct snd_ad1843 *ad1843, + unsigned int framerate, + snd_pcm_format_t fmt, + unsigned int channels) +{ + int da_fmt = 0; + + switch (fmt) { + case SNDRV_PCM_FORMAT_S8: da_fmt = 0; break; + case SNDRV_PCM_FORMAT_U8: da_fmt = 0; break; + case SNDRV_PCM_FORMAT_S16_LE: da_fmt = 1; break; + case SNDRV_PCM_FORMAT_MU_LAW: da_fmt = 2; break; + case SNDRV_PCM_FORMAT_A_LAW: da_fmt = 3; break; + default: break; + } + + ad1843_write_bits(ad1843, &ad1843_C3C, framerate); + ad1843_write_multi(ad1843, 2, + &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt); +} + +void ad1843_shutdown_adc(struct snd_ad1843 *ad1843) +{ + /* nothing to do */ +} + +/* + * Fully initialize the ad1843. As described in the AD1843 data + * sheet, section "START-UP SEQUENCE". The numbered comments are + * subsection headings from the data sheet. See the data sheet, pages + * 52-54, for more info. + * + * return 0 on success, -errno on failure. */ + +int ad1843_init(struct snd_ad1843 *ad1843) +{ + unsigned long later; + + if (ad1843_read_bits(ad1843, &ad1843_INIT) != 0) { + printk(KERN_ERR "ad1843: AD1843 won't initialize\n"); + return -EIO; + } + + ad1843_write_bits(ad1843, &ad1843_SCF, 1); + + /* 4. Put the conversion resources into standby. */ + ad1843_write_bits(ad1843, &ad1843_PDNI, 0); + later = jiffies + msecs_to_jiffies(500); + + while (ad1843_read_bits(ad1843, &ad1843_PDNO)) { + if (time_after(jiffies, later)) { + printk(KERN_ERR + "ad1843: AD1843 won't power up\n"); + return -EIO; + } + schedule_timeout_interruptible(5); + } + + /* 5. Power up the clock generators and enable clock output pins. */ + ad1843_write_multi(ad1843, 3, + &ad1843_C1EN, 1, + &ad1843_C2EN, 1, + &ad1843_C3EN, 1); + + /* 6. Configure conversion resources while they are in standby. */ + + /* DAC1/2 use clock 1/2 as source, ADC uses clock 3. Always. */ + ad1843_write_multi(ad1843, 4, + &ad1843_DA1C, 1, + &ad1843_DA2C, 2, + &ad1843_ADLC, 3, + &ad1843_ADRC, 3); + + /* 7. Enable conversion resources. */ + ad1843_write_bits(ad1843, &ad1843_ADTLK, 1); + ad1843_write_multi(ad1843, 7, + &ad1843_ANAEN, 1, + &ad1843_AAMEN, 1, + &ad1843_DA1EN, 1, + &ad1843_DA2EN, 1, + &ad1843_DDMEN, 1, + &ad1843_ADLEN, 1, + &ad1843_ADREN, 1); + + /* 8. Configure conversion resources while they are enabled. */ + + /* set gain to 0 for all channels */ + ad1843_set_gain(ad1843, AD1843_GAIN_RECLEV, 0); + ad1843_set_gain(ad1843, AD1843_GAIN_LINE, 0); + ad1843_set_gain(ad1843, AD1843_GAIN_LINE_2, 0); + ad1843_set_gain(ad1843, AD1843_GAIN_MIC, 0); + ad1843_set_gain(ad1843, AD1843_GAIN_PCM_0, 0); + ad1843_set_gain(ad1843, AD1843_GAIN_PCM_1, 0); + + /* Unmute all channels. */ + /* DAC1 */ + ad1843_write_multi(ad1843, 2, &ad1843_LDA1GM, 0, &ad1843_RDA1GM, 0); + /* DAC2 */ + ad1843_write_multi(ad1843, 2, &ad1843_LDA2GM, 0, &ad1843_RDA2GM, 0); + + /* Set default recording source to Line In and set + * mic gain to +20 dB. + */ + ad1843_set_recsrc(ad1843, 2); + ad1843_write_multi(ad1843, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1); + + /* Set Speaker Out level to +/- 4V and unmute it. */ + ad1843_write_multi(ad1843, 3, + &ad1843_HPOS, 1, + &ad1843_HPOM, 0, + &ad1843_MPOM, 0); + + return 0; +} diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c new file mode 100644 index 00000000000..4c63504348d --- /dev/null +++ b/sound/mips/sgio2audio.c @@ -0,0 +1,1006 @@ +/* + * Sound driver for Silicon Graphics O2 Workstations A/V board audio. + * + * Copyright 2003 Vivien Chappelier + * Copyright 2008 Thomas Bogendoerfer + * Mxier part taken from mace_audio.c: + * Copyright 2007 Thorben Jändling + * + * 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 +#define SNDRV_GET_ID +#include +#include + + +MODULE_AUTHOR("Vivien Chappelier "); +MODULE_DESCRIPTION("SGI O2 Audio"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{Silicon Graphics, O2 Audio}}"); + +static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ +static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ + +module_param(index, int, 0444); +MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard."); +module_param(id, charp, 0444); +MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard."); + + +#define AUDIO_CONTROL_RESET BIT(0) /* 1: reset audio interface */ +#define AUDIO_CONTROL_CODEC_PRESENT BIT(1) /* 1: codec detected */ + +#define CODEC_CONTROL_WORD_SHIFT 0 +#define CODEC_CONTROL_READ BIT(16) +#define CODEC_CONTROL_ADDRESS_SHIFT 17 + +#define CHANNEL_CONTROL_RESET BIT(10) /* 1: reset channel */ +#define CHANNEL_DMA_ENABLE BIT(9) /* 1: enable DMA transfer */ +#define CHANNEL_INT_THRESHOLD_DISABLED (0 << 5) /* interrupt disabled */ +#define CHANNEL_INT_THRESHOLD_25 (1 << 5) /* int on buffer >25% full */ +#define CHANNEL_INT_THRESHOLD_50 (2 << 5) /* int on buffer >50% full */ +#define CHANNEL_INT_THRESHOLD_75 (3 << 5) /* int on buffer >75% full */ +#define CHANNEL_INT_THRESHOLD_EMPTY (4 << 5) /* int on buffer empty */ +#define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5) /* int on buffer !empty */ +#define CHANNEL_INT_THRESHOLD_FULL (6 << 5) /* int on buffer empty */ +#define CHANNEL_INT_THRESHOLD_NOT_FULL (7 << 5) /* int on buffer !empty */ + +#define CHANNEL_RING_SHIFT 12 +#define CHANNEL_RING_SIZE (1 << CHANNEL_RING_SHIFT) +#define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1) + +#define CHANNEL_LEFT_SHIFT 40 +#define CHANNEL_RIGHT_SHIFT 8 + +struct snd_sgio2audio_chan { + int idx; + struct snd_pcm_substream *substream; + int pos; + snd_pcm_uframes_t size; + spinlock_t lock; +}; + +/* definition of the chip-specific record */ +struct snd_sgio2audio { + struct snd_card *card; + + /* codec */ + struct snd_ad1843 ad1843; + spinlock_t ad1843_lock; + + /* channels */ + struct snd_sgio2audio_chan channel[3]; + + /* resources */ + void *ring_base; + dma_addr_t ring_base_dma; +}; + +/* AD1843 access */ + +/* + * read_ad1843_reg returns the current contents of a 16 bit AD1843 register. + * + * Returns unsigned register value on success, -errno on failure. + */ +static int read_ad1843_reg(void *priv, int reg) +{ + struct snd_sgio2audio *chip = priv; + int val; + unsigned long flags; + + spin_lock_irqsave(&chip->ad1843_lock, flags); + + writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) | + CODEC_CONTROL_READ, &mace->perif.audio.codec_control); + wmb(); + val = readq(&mace->perif.audio.codec_control); /* flush bus */ + udelay(200); + + val = readq(&mace->perif.audio.codec_read); + + spin_unlock_irqrestore(&chip->ad1843_lock, flags); + return val; +} + +/* + * write_ad1843_reg writes the specified value to a 16 bit AD1843 register. + */ +static int write_ad1843_reg(void *priv, int reg, int word) +{ + struct snd_sgio2audio *chip = priv; + int val; + unsigned long flags; + + spin_lock_irqsave(&chip->ad1843_lock, flags); + + writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) | + (word << CODEC_CONTROL_WORD_SHIFT), + &mace->perif.audio.codec_control); + wmb(); + val = readq(&mace->perif.audio.codec_control); /* flush bus */ + udelay(200); + + spin_unlock_irqrestore(&chip->ad1843_lock, flags); + return 0; +} + +static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843, + (int)kcontrol->private_value); + return 0; +} + +static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); + int vol; + + vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value); + + ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF; + ucontrol->value.integer.value[1] = vol & 0xFF; + + return 0; +} + +static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); + int newvol, oldvol; + + oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value); + newvol = (ucontrol->value.integer.value[0] << 8) | + ucontrol->value.integer.value[1]; + + newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value, + newvol); + + return newvol != oldvol; +} + +static int sgio2audio_source_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char *texts[3] = { + "Cam Mic", "Mic", "Line" + }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 3; + if (uinfo->value.enumerated.item >= 3) + uinfo->value.enumerated.item = 1; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int sgio2audio_source_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843); + return 0; +} + +static int sgio2audio_source_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); + int newsrc, oldsrc; + + oldsrc = ad1843_get_recsrc(&chip->ad1843); + newsrc = ad1843_set_recsrc(&chip->ad1843, + ucontrol->value.enumerated.item[0]); + + return newsrc != oldsrc; +} + +/* dac1/pcm0 mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Volume", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_PCM_0, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + +/* dac2/pcm1 mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Volume", + .index = 1, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_PCM_1, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + +/* record level mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_reclevel __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_RECLEV, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + +/* record level source control */ +static struct snd_kcontrol_new sgio2audio_ctrl_recsource __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = sgio2audio_source_info, + .get = sgio2audio_source_get, + .put = sgio2audio_source_put, +}; + +/* line mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_line __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line Playback Volume", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_LINE, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + +/* cd mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_cd __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line Playback Volume", + .index = 1, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_LINE_2, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + +/* mic mixer control */ +static struct snd_kcontrol_new sgio2audio_ctrl_mic __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = AD1843_GAIN_MIC, + .info = sgio2audio_gain_info, + .get = sgio2audio_gain_get, + .put = sgio2audio_gain_put, +}; + + +static int __devinit snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip) +{ + int err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip)); + if (err < 0) + return err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip)); + if (err < 0) + return err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip)); + if (err < 0) + return err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_recsource, chip)); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_line, chip)); + if (err < 0) + return err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_cd, chip)); + if (err < 0) + return err; + + err = snd_ctl_add(chip->card, + snd_ctl_new1(&sgio2audio_ctrl_mic, chip)); + if (err < 0) + return err; + + return 0; +} + +/* low-level audio interface DMA */ + +/* get data out of bounce buffer, count must be a multiple of 32 */ +/* returns 1 if a period has elapsed */ +static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip, + unsigned int ch, unsigned int count) +{ + int ret; + unsigned long src_base, src_pos, dst_mask; + unsigned char *dst_base; + int dst_pos; + u64 *src; + s16 *dst; + u64 x; + unsigned long flags; + struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime; + + spin_lock_irqsave(&chip->channel[ch].lock, flags); + + src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT); + src_pos = readq(&mace->perif.audio.chan[ch].read_ptr); + dst_base = runtime->dma_area; + dst_pos = chip->channel[ch].pos; + dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1; + + /* check if a period has elapsed */ + chip->channel[ch].size += (count >> 3); /* in frames */ + ret = chip->channel[ch].size >= runtime->period_size; + chip->channel[ch].size %= runtime->period_size; + + while (count) { + src = (u64 *)(src_base + src_pos); + dst = (s16 *)(dst_base + dst_pos); + + x = *src; + dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff; + dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff; + + src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK; + dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask; + count -= sizeof(u64); + } + + writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */ + chip->channel[ch].pos = dst_pos; + + spin_unlock_irqrestore(&chip->channel[ch].lock, flags); + return ret; +} + +/* put some DMA data in bounce buffer, count must be a multiple of 32 */ +/* returns 1 if a period has elapsed */ +static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip, + unsigned int ch, unsigned int count) +{ + int ret; + s64 l, r; + unsigned long dst_base, dst_pos, src_mask; + unsigned char *src_base; + int src_pos; + u64 *dst; + s16 *src; + unsigned long flags; + struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime; + + spin_lock_irqsave(&chip->channel[ch].lock, flags); + + dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT); + dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr); + src_base = runtime->dma_area; + src_pos = chip->channel[ch].pos; + src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1; + + /* check if a period has elapsed */ + chip->channel[ch].size += (count >> 3); /* in frames */ + ret = chip->channel[ch].size >= runtime->period_size; + chip->channel[ch].size %= runtime->period_size; + + while (count) { + src = (s16 *)(src_base + src_pos); + dst = (u64 *)(dst_base + dst_pos); + + l = src[0]; /* sign extend */ + r = src[1]; /* sign extend */ + + *dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) | + ((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT); + + dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK; + src_pos = (src_pos + 2 * sizeof(s16)) & src_mask; + count -= sizeof(u64); + } + + writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */ + chip->channel[ch].pos = src_pos; + + spin_unlock_irqrestore(&chip->channel[ch].lock, flags); + return ret; +} + +static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_sgio2audio_chan *chan = substream->runtime->private_data; + int ch = chan->idx; + + /* reset DMA channel */ + writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control); + udelay(10); + writeq(0, &mace->perif.audio.chan[ch].control); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /* push a full buffer */ + snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32); + } + /* set DMA to wake on 50% empty and enable interrupt */ + writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50, + &mace->perif.audio.chan[ch].control); + return 0; +} + +static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio_chan *chan = substream->runtime->private_data; + + writeq(0, &mace->perif.audio.chan[chan->idx].control); + return 0; +} + +static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id) +{ + struct snd_sgio2audio_chan *chan = dev_id; + struct snd_pcm_substream *substream; + struct snd_sgio2audio *chip; + int count, ch; + + substream = chan->substream; + chip = snd_pcm_substream_chip(substream); + ch = chan->idx; + + /* empty the ring */ + count = CHANNEL_RING_SIZE - + readq(&mace->perif.audio.chan[ch].depth) - 32; + if (snd_sgio2audio_dma_pull_frag(chip, ch, count)) + snd_pcm_period_elapsed(substream); + + return IRQ_HANDLED; +} + +static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id) +{ + struct snd_sgio2audio_chan *chan = dev_id; + struct snd_pcm_substream *substream; + struct snd_sgio2audio *chip; + int count, ch; + + substream = chan->substream; + chip = snd_pcm_substream_chip(substream); + ch = chan->idx; + /* fill the ring */ + count = CHANNEL_RING_SIZE - + readq(&mace->perif.audio.chan[ch].depth) - 32; + if (snd_sgio2audio_dma_push_frag(chip, ch, count)) + snd_pcm_period_elapsed(substream); + + return IRQ_HANDLED; +} + +static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id) +{ + struct snd_sgio2audio_chan *chan = dev_id; + struct snd_pcm_substream *substream; + + substream = chan->substream; + snd_sgio2audio_dma_stop(substream); + snd_sgio2audio_dma_start(substream); + return IRQ_HANDLED; +} + +/* PCM part */ +/* PCM hardware definition */ +static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER), + .formats = SNDRV_PCM_FMTBIT_S16_BE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 65536, + .period_bytes_min = 32768, + .period_bytes_max = 65536, + .periods_min = 1, + .periods_max = 1024, +}; + +/* PCM playback open callback */ +static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw = snd_sgio2audio_pcm_hw; + runtime->private_data = &chip->channel[1]; + return 0; +} + +static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw = snd_sgio2audio_pcm_hw; + runtime->private_data = &chip->channel[2]; + return 0; +} + +/* PCM capture open callback */ +static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw = snd_sgio2audio_pcm_hw; + runtime->private_data = &chip->channel[0]; + return 0; +} + +/* PCM close callback */ +static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->private_data = NULL; + return 0; +} + + +/* hw_params callback */ +static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + int size = params_buffer_bytes(hw_params); + + /* alloc virtual 'dma' area */ + if (runtime->dma_area) + vfree(runtime->dma_area); + runtime->dma_area = vmalloc(size); + if (runtime->dma_area == NULL) + return -ENOMEM; + runtime->dma_bytes = size; + return 0; +} + +/* hw_free callback */ +static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream) +{ + if (substream->runtime->dma_area) + vfree(substream->runtime->dma_area); + substream->runtime->dma_area = NULL; + return 0; +} + +/* prepare callback */ +static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_sgio2audio_chan *chan = substream->runtime->private_data; + int ch = chan->idx; + unsigned long flags; + + spin_lock_irqsave(&chip->channel[ch].lock, flags); + + /* Setup the pseudo-dma transfer pointers. */ + chip->channel[ch].pos = 0; + chip->channel[ch].size = 0; + chip->channel[ch].substream = substream; + + /* set AD1843 format */ + /* hardware format is always S16_LE */ + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ad1843_setup_dac(&chip->ad1843, + ch - 1, + runtime->rate, + SNDRV_PCM_FORMAT_S16_LE, + runtime->channels); + break; + case SNDRV_PCM_STREAM_CAPTURE: + ad1843_setup_adc(&chip->ad1843, + runtime->rate, + SNDRV_PCM_FORMAT_S16_LE, + runtime->channels); + break; + } + spin_unlock_irqrestore(&chip->channel[ch].lock, flags); + return 0; +} + +/* trigger callback */ +static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* start the PCM engine */ + snd_sgio2audio_dma_start(substream); + break; + case SNDRV_PCM_TRIGGER_STOP: + /* stop the PCM engine */ + snd_sgio2audio_dma_stop(substream); + break; + default: + return -EINVAL; + } + return 0; +} + +/* pointer callback */ +static snd_pcm_uframes_t +snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); + struct snd_sgio2audio_chan *chan = substream->runtime->private_data; + + /* get the current hardware pointer */ + return bytes_to_frames(substream->runtime, + chip->channel[chan->idx].pos); +} + +/* get the physical page pointer on the given offset */ +static struct page *snd_sgio2audio_page(struct snd_pcm_substream *substream, + unsigned long offset) +{ + return vmalloc_to_page(substream->runtime->dma_area + offset); +} + +/* operators */ +static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { + .open = snd_sgio2audio_playback1_open, + .close = snd_sgio2audio_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_sgio2audio_pcm_hw_params, + .hw_free = snd_sgio2audio_pcm_hw_free, + .prepare = snd_sgio2audio_pcm_prepare, + .trigger = snd_sgio2audio_pcm_trigger, + .pointer = snd_sgio2audio_pcm_pointer, + .page = snd_sgio2audio_page, +}; + +static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { + .open = snd_sgio2audio_playback2_open, + .close = snd_sgio2audio_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_sgio2audio_pcm_hw_params, + .hw_free = snd_sgio2audio_pcm_hw_free, + .prepare = snd_sgio2audio_pcm_prepare, + .trigger = snd_sgio2audio_pcm_trigger, + .pointer = snd_sgio2audio_pcm_pointer, + .page = snd_sgio2audio_page, +}; + +static struct snd_pcm_ops snd_sgio2audio_capture_ops = { + .open = snd_sgio2audio_capture_open, + .close = snd_sgio2audio_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_sgio2audio_pcm_hw_params, + .hw_free = snd_sgio2audio_pcm_hw_free, + .prepare = snd_sgio2audio_pcm_prepare, + .trigger = snd_sgio2audio_pcm_trigger, + .pointer = snd_sgio2audio_pcm_pointer, + .page = snd_sgio2audio_page, +}; + +/* + * definitions of capture are omitted here... + */ + +/* create a pcm device */ +static int __devinit snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip) +{ + struct snd_pcm *pcm; + int err; + + /* create first pcm device with one outputs and one input */ + err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm); + if (err < 0) + return err; + + pcm->private_data = chip; + strcpy(pcm->name, "SGI O2 DAC1"); + + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_sgio2audio_playback1_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_sgio2audio_capture_ops); + + /* create second pcm device with one outputs and no input */ + err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm); + if (err < 0) + return err; + + pcm->private_data = chip; + strcpy(pcm->name, "SGI O2 DAC2"); + + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_sgio2audio_playback2_ops); + + return 0; +} + +static struct { + int idx; + int irq; + irqreturn_t (*isr)(int, void *); + const char *desc; +} snd_sgio2_isr_table[] = { + { + .idx = 0, + .irq = MACEISA_AUDIO1_DMAT_IRQ, + .isr = snd_sgio2audio_dma_in_isr, + .desc = "Capture DMA Channel 0" + }, { + .idx = 0, + .irq = MACEISA_AUDIO1_OF_IRQ, + .isr = snd_sgio2audio_error_isr, + .desc = "Capture Overflow" + }, { + .idx = 1, + .irq = MACEISA_AUDIO2_DMAT_IRQ, + .isr = snd_sgio2audio_dma_out_isr, + .desc = "Playback DMA Channel 1" + }, { + .idx = 1, + .irq = MACEISA_AUDIO2_MERR_IRQ, + .isr = snd_sgio2audio_error_isr, + .desc = "Memory Error Channel 1" + }, { + .idx = 2, + .irq = MACEISA_AUDIO3_DMAT_IRQ, + .isr = snd_sgio2audio_dma_out_isr, + .desc = "Playback DMA Channel 2" + }, { + .idx = 2, + .irq = MACEISA_AUDIO3_MERR_IRQ, + .isr = snd_sgio2audio_error_isr, + .desc = "Memory Error Channel 2" + } +}; + +/* ALSA driver */ + +static int snd_sgio2audio_free(struct snd_sgio2audio *chip) +{ + int i; + + /* reset interface */ + writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control); + udelay(1); + writeq(0, &mace->perif.audio.control); + + /* release IRQ's */ + for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) + free_irq(snd_sgio2_isr_table[i].irq, + &chip->channel[snd_sgio2_isr_table[i].idx]); + + dma_free_coherent(NULL, MACEISA_RINGBUFFERS_SIZE, + chip->ring_base, chip->ring_base_dma); + + /* release card data */ + kfree(chip); + return 0; +} + +static int snd_sgio2audio_dev_free(struct snd_device *device) +{ + struct snd_sgio2audio *chip = device->device_data; + + return snd_sgio2audio_free(chip); +} + +static struct snd_device_ops ops = { + .dev_free = snd_sgio2audio_dev_free, +}; + +static int __devinit snd_sgio2audio_create(struct snd_card *card, + struct snd_sgio2audio **rchip) +{ + struct snd_sgio2audio *chip; + int i, err; + + *rchip = NULL; + + /* check if a codec is attached to the interface */ + /* (Audio or Audio/Video board present) */ + if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) + return -ENOENT; + + chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + chip->card = card; + + chip->ring_base = dma_alloc_coherent(NULL, MACEISA_RINGBUFFERS_SIZE, + &chip->ring_base_dma, GFP_USER); + if (chip->ring_base == NULL) { + printk(KERN_ERR + "sgio2audio: could not allocate ring buffers\n"); + kfree(chip); + return -ENOMEM; + } + + spin_lock_init(&chip->ad1843_lock); + + /* initialize channels */ + for (i = 0; i < 3; i++) { + spin_lock_init(&chip->channel[i].lock); + chip->channel[i].idx = i; + } + + /* allocate IRQs */ + for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) { + if (request_irq(snd_sgio2_isr_table[i].irq, + snd_sgio2_isr_table[i].isr, + 0, + snd_sgio2_isr_table[i].desc, + &chip->channel[snd_sgio2_isr_table[i].idx])) { + snd_sgio2audio_free(chip); + printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n", + snd_sgio2_isr_table[i].irq); + return -EBUSY; + } + } + + /* reset the interface */ + writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control); + udelay(1); + writeq(0, &mace->perif.audio.control); + msleep_interruptible(1); /* give time to recover */ + + /* set ring base */ + writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase); + + /* attach the AD1843 codec */ + chip->ad1843.read = read_ad1843_reg; + chip->ad1843.write = write_ad1843_reg; + chip->ad1843.chip = chip; + + /* initialize the AD1843 codec */ + err = ad1843_init(&chip->ad1843); + if (err < 0) { + snd_sgio2audio_free(chip); + return err; + } + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) { + snd_sgio2audio_free(chip); + return err; + } + *rchip = chip; + return 0; +} + +static int __devinit snd_sgio2audio_probe(struct platform_device *pdev) +{ + struct snd_card *card; + struct snd_sgio2audio *chip; + int err; + + card = snd_card_new(index, id, THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + err = snd_sgio2audio_create(card, &chip); + if (err < 0) { + snd_card_free(card); + return err; + } + snd_card_set_dev(card, &pdev->dev); + + err = snd_sgio2audio_new_pcm(chip); + if (err < 0) { + snd_card_free(card); + return err; + } + err = snd_sgio2audio_new_mixer(chip); + if (err < 0) { + snd_card_free(card); + return err; + } + + strcpy(card->driver, "SGI O2 Audio"); + strcpy(card->shortname, "SGI O2 Audio"); + sprintf(card->longname, "%s irq %i-%i", + card->shortname, + MACEISA_AUDIO1_DMAT_IRQ, + MACEISA_AUDIO3_MERR_IRQ); + + err = snd_card_register(card); + if (err < 0) { + snd_card_free(card); + return err; + } + platform_set_drvdata(pdev, card); + return 0; +} + +static int __exit snd_sgio2audio_remove(struct platform_device *pdev) +{ + struct snd_card *card = platform_get_drvdata(pdev); + + snd_card_free(card); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver sgio2audio_driver = { + .probe = snd_sgio2audio_probe, + .remove = __devexit_p(snd_sgio2audio_remove), + .driver = { + .name = "sgio2audio", + .owner = THIS_MODULE, + } +}; + +static int __init alsa_card_sgio2audio_init(void) +{ + return platform_driver_register(&sgio2audio_driver); +} + +static void __exit alsa_card_sgio2audio_exit(void) +{ + platform_driver_unregister(&sgio2audio_driver); +} + +module_init(alsa_card_sgio2audio_init) +module_exit(alsa_card_sgio2audio_exit) -- GitLab From 80ca9a706b458d09b8cc8d5258bb61957f66ca5e Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Sun, 13 Jul 2008 13:58:12 +0200 Subject: [PATCH 1737/2509] ALSA: correct kcalloc usage kcalloc is supposed to be called with the count as its first argument and the element size as the second. Both arguments are size_t so does not affect correctness. This callsite is during module_init and therefore not performance critical. Another patch will optimize the case when the count is variable but the size is fixed. Signed-off-by: Milton Miller Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/nm256/nm256.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 7efb838d18a..06d13e71711 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1302,8 +1302,8 @@ snd_nm256_mixer(struct nm256 *chip) .read = snd_nm256_ac97_read, }; - chip->ac97_regs = kcalloc(sizeof(short), - ARRAY_SIZE(nm256_ac97_init_val), GFP_KERNEL); + chip->ac97_regs = kcalloc(ARRAY_SIZE(nm256_ac97_init_val), + sizeof(short), GFP_KERNEL); if (! chip->ac97_regs) return -ENOMEM; -- GitLab From 32b23e9a7331fce57eb0af52e19e8409fdef831b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 13 Jul 2008 14:29:41 -0700 Subject: [PATCH 1738/2509] x86: max_low_pfn_mapped fix #4 only add direct mapping for aperture Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar --- arch/x86/kernel/pci-gart_64.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index a614ee10f84..c3fe78406d1 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -679,11 +679,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info) /* 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<>PAGE_SHIFT); + init_memory_mapping(start_pfn< Date: Sun, 13 Jul 2008 14:30:35 -0700 Subject: [PATCH 1739/2509] x86: get x86_phys_bits early when try to make hpet_enable use io_remap instead fixmap got ioremap: invalid physical address fed00000 ------------[ cut here ]------------ WARNING: at arch/x86/mm/ioremap.c:161 __ioremap_caller+0x8c/0x2f3() Modules linked in: Pid: 0, comm: swapper Not tainted 2.6.26-rc9-tip-01873-ga9827e7-dirty #358 Call Trace: [] warn_on_slowpath+0x6c/0xa7 [] ? __slab_alloc+0x20a/0x3fb [] ? mpol_new+0x88/0x17d [] ? mcount_call+0x5/0x31 [] ? mcount_call+0x5/0x31 [] __ioremap_caller+0x8c/0x2f3 [] ? hpet_enable+0x39/0x241 [] ? mcount_call+0x5/0x31 [] ioremap_nocache+0x2a/0x40 [] hpet_enable+0x39/0x241 [] hpet_time_init+0x21/0x4e [] start_kernel+0x302/0x395 [] x86_64_start_reservations+0xb9/0xd4 [] ? x86_64_init_pda+0x39/0x4f [] x86_64_start_kernel+0xec/0x107 ---[ end trace a7919e7f17c0a725 ]--- it seems for amd system that is set later... try to move setting early in early_identify_cpu. and remove same code for intel and centaur. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/centaur_64.c | 10 ---------- arch/x86/kernel/cpu/common_64.c | 14 ++++++++------ arch/x86/kernel/cpu/intel_64.c | 10 ---------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/arch/x86/kernel/cpu/centaur_64.c b/arch/x86/kernel/cpu/centaur_64.c index 2026d2119cd..1d181c40e2e 100644 --- a/arch/x86/kernel/cpu/centaur_64.c +++ b/arch/x86/kernel/cpu/centaur_64.c @@ -16,16 +16,6 @@ static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) static void __cpuinit init_centaur(struct cpuinfo_x86 *c) { - /* Cache sizes */ - unsigned n; - - n = c->extended_cpuid_level; - if (n >= 0x80000008) { - unsigned eax = cpuid_eax(0x80000008); - c->x86_virt_bits = (eax >> 8) & 0xff; - c->x86_phys_bits = eax & 0xff; - } - if (c->x86 == 0x6 && c->x86_model >= 0xf) { c->x86_cache_alignment = c->x86_clflush_size * 2; set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index 36537ab9e56..7b8cc72feb4 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c @@ -98,7 +98,7 @@ int __cpuinit get_model_name(struct cpuinfo_x86 *c) void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) { - unsigned int n, dummy, eax, ebx, ecx, edx; + unsigned int n, dummy, ebx, ecx, edx; n = c->extended_cpuid_level; @@ -121,11 +121,6 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", c->x86_cache_size, ecx & 0xFF); } - if (n >= 0x80000008) { - cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); - c->x86_virt_bits = (eax >> 8) & 0xff; - c->x86_phys_bits = eax & 0xff; - } } void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -314,6 +309,13 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) if (c->extended_cpuid_level >= 0x80000007) c->x86_power = cpuid_edx(0x80000007); + if (c->extended_cpuid_level >= 0x80000008) { + u32 eax = cpuid_eax(0x80000008); + + c->x86_virt_bits = (eax >> 8) & 0xff; + c->x86_phys_bits = eax & 0xff; + } + /* Assume all 64-bit CPUs support 32-bit syscall */ set_cpu_cap(c, X86_FEATURE_SYSCALL32); diff --git a/arch/x86/kernel/cpu/intel_64.c b/arch/x86/kernel/cpu/intel_64.c index 02f773399e3..1019c58d39f 100644 --- a/arch/x86/kernel/cpu/intel_64.c +++ b/arch/x86/kernel/cpu/intel_64.c @@ -54,9 +54,6 @@ static void __cpuinit srat_detect_node(void) static void __cpuinit init_intel(struct cpuinfo_x86 *c) { - /* Cache sizes */ - unsigned n; - init_intel_cacheinfo(c); if (c->cpuid_level > 9) { unsigned eax = cpuid_eax(10); @@ -78,13 +75,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has_bts) ds_init_intel(c); - n = c->extended_cpuid_level; - if (n >= 0x80000008) { - unsigned eax = cpuid_eax(0x80000008); - c->x86_virt_bits = (eax >> 8) & 0xff; - c->x86_phys_bits = eax & 0xff; - } - if (c->x86 == 15) c->x86_cache_alignment = c->x86_clflush_size * 2; if (c->x86 == 6) -- GitLab From 2387ce57a8167490d3b34a7e1ffa9a64a1a76244 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 13 Jul 2008 14:50:56 -0700 Subject: [PATCH 1740/2509] x86: make 64bit hpet_set_mapping to use ioremap too, v2 keep the one for VSYSCALL_HPET Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/hpet.c | 20 ++++---------------- include/asm-x86/fixmap_64.h | 1 - 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ea230ec6905..0ea6a19bfdf 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -36,26 +36,15 @@ static inline void hpet_writel(unsigned long d, unsigned long a) } #ifdef CONFIG_X86_64 - #include - -static inline void hpet_set_mapping(void) -{ - set_fixmap_nocache(FIX_HPET_BASE, hpet_address); - __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); - hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); -} - -static inline void hpet_clear_mapping(void) -{ - hpet_virt_address = NULL; -} - -#else +#endif static inline void hpet_set_mapping(void) { hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); +#ifdef CONFIG_X86_64 + __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); +#endif } static inline void hpet_clear_mapping(void) @@ -63,7 +52,6 @@ static inline void hpet_clear_mapping(void) iounmap(hpet_virt_address); hpet_virt_address = NULL; } -#endif /* * HPET command line enable / disable diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index 6a4789d57e6..00f3d74a052 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h @@ -40,7 +40,6 @@ enum fixed_addresses { VSYSCALL_HPET, FIX_DBGP_BASE, FIX_EARLYCON_MEM_BASE, - FIX_HPET_BASE, FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, -- GitLab From fe0a3fe324811385b64790d42079bf534798a0cd Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 14 Jul 2008 09:54:43 +0200 Subject: [PATCH 1741/2509] ALSA: Release v1.0.17 Signed-off-by: Jaroslav Kysela --- include/sound/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/version.h b/include/sound/version.h index 29a5b227312..6b78aff273a 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.17rc3" +#define CONFIG_SND_VERSION "1.0.17" #define CONFIG_SND_DATE "" -- GitLab From 727c6742c29e46177951fdc8f6758085e03bb981 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 13 Jul 2008 12:46:36 -0500 Subject: [PATCH 1742/2509] pcmcia: Fix ide-cs sparse warning Sparse shows the following warning: CHECK drivers/ide/legacy/ide-cs.c drivers/ide/legacy/ide-cs.c:378:6: warning: symbol 'ide_release' was not declared. Should it be static? Signed-off-by: Larry Finger CC: Bartlomiej Zolnierkiewicz Signed-off-by: Dominik Brodowski --- drivers/ide/legacy/ide-cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 8b8b20d8691..99af3bb6c46 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -376,7 +376,7 @@ failed: ======================================================================*/ -void ide_release(struct pcmcia_device *link) +static void ide_release(struct pcmcia_device *link) { ide_info_t *info = link->priv; ide_hwif_t *hwif = info->hwif; -- GitLab From 9689b336e193680fc0fcaa33829dc670637e9c98 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:57:23 +0200 Subject: [PATCH 1743/2509] [S390] cio: Clear correct bit in cio_release_console(). Fallout from the console isc 7 -> 1 change. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/cio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index b32d7eb3d81..7b5969ed05c 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -810,7 +810,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm = 0; cio_modify(&console_subchannel); - ctl_clear_bit(6, 24); + ctl_clear_bit(6, 30); console_subchannel_in_use = 0; } -- GitLab From b1c02d9110e72ec510ec9b038f9564e3c0d87384 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Mon, 14 Jul 2008 09:57:24 +0200 Subject: [PATCH 1744/2509] [S390] cio: Use locks when accessing /sys/firmware/cpi data. Mutex locks are used to avoid problems when /sys/firmware/cpi data are accessed to in parallel. Signed-off-by: Michael Ernst Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_cpi_sys.c | 45 +++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index 9f37456222e..005f330ed92 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -27,6 +27,8 @@ #define CPI_LENGTH_NAME 8 #define CPI_LENGTH_LEVEL 16 +static DEFINE_MUTEX(sclp_cpi_mutex); + struct cpi_evbuf { struct evbuf_header header; u8 id_format; @@ -223,7 +225,12 @@ static void set_string(char *attr, const char *value) static ssize_t system_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { - return snprintf(page, PAGE_SIZE, "%s\n", system_name); + int rc; + + mutex_lock(&sclp_cpi_mutex); + rc = snprintf(page, PAGE_SIZE, "%s\n", system_name); + mutex_unlock(&sclp_cpi_mutex); + return rc; } static ssize_t system_name_store(struct kobject *kobj, @@ -237,7 +244,9 @@ static ssize_t system_name_store(struct kobject *kobj, if (rc) return rc; + mutex_lock(&sclp_cpi_mutex); set_string(system_name, buf); + mutex_unlock(&sclp_cpi_mutex); return len; } @@ -248,7 +257,12 @@ static struct kobj_attribute system_name_attr = static ssize_t sysplex_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { - return snprintf(page, PAGE_SIZE, "%s\n", sysplex_name); + int rc; + + mutex_lock(&sclp_cpi_mutex); + rc = snprintf(page, PAGE_SIZE, "%s\n", sysplex_name); + mutex_unlock(&sclp_cpi_mutex); + return rc; } static ssize_t sysplex_name_store(struct kobject *kobj, @@ -262,7 +276,9 @@ static ssize_t sysplex_name_store(struct kobject *kobj, if (rc) return rc; + mutex_lock(&sclp_cpi_mutex); set_string(sysplex_name, buf); + mutex_unlock(&sclp_cpi_mutex); return len; } @@ -273,7 +289,12 @@ static struct kobj_attribute sysplex_name_attr = static ssize_t system_type_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { - return snprintf(page, PAGE_SIZE, "%s\n", system_type); + int rc; + + mutex_lock(&sclp_cpi_mutex); + rc = snprintf(page, PAGE_SIZE, "%s\n", system_type); + mutex_unlock(&sclp_cpi_mutex); + return rc; } static ssize_t system_type_store(struct kobject *kobj, @@ -287,7 +308,9 @@ static ssize_t system_type_store(struct kobject *kobj, if (rc) return rc; + mutex_lock(&sclp_cpi_mutex); set_string(system_type, buf); + mutex_unlock(&sclp_cpi_mutex); return len; } @@ -298,8 +321,11 @@ static struct kobj_attribute system_type_attr = static ssize_t system_level_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { - unsigned long long level = system_level; + unsigned long long level; + mutex_lock(&sclp_cpi_mutex); + level = system_level; + mutex_unlock(&sclp_cpi_mutex); return snprintf(page, PAGE_SIZE, "%#018llx\n", level); } @@ -320,8 +346,9 @@ static ssize_t system_level_store(struct kobject *kobj, if (*endp) return -EINVAL; + mutex_lock(&sclp_cpi_mutex); system_level = level; - + mutex_unlock(&sclp_cpi_mutex); return len; } @@ -334,7 +361,9 @@ static ssize_t set_store(struct kobject *kobj, { int rc; + mutex_lock(&sclp_cpi_mutex); rc = cpi_req(); + mutex_unlock(&sclp_cpi_mutex); if (rc) return rc; @@ -373,12 +402,16 @@ int sclp_cpi_set_data(const char *system, const char *sysplex, const char *type, if (rc) return rc; + mutex_lock(&sclp_cpi_mutex); set_string(system_name, system); set_string(sysplex_name, sysplex); set_string(system_type, type); system_level = level; - return cpi_req(); + rc = cpi_req(); + mutex_unlock(&sclp_cpi_mutex); + + return rc; } EXPORT_SYMBOL(sclp_cpi_set_data); -- GitLab From bb0ca330a7e273cdecebae0283c9d267f60fe363 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 14 Jul 2008 09:57:25 +0200 Subject: [PATCH 1745/2509] [S390] qdio: Repair timeout handling for qdio_shutdown If qdio shutdown runs in parallel with a channel error, the qdio_timeout_handler might not be triggered. In this case neither state INACTIVE nor state ERR is reached and the following wait_event hangs forever. Solution: do not make use of ccw_device_set_timeout(), but add a timeout to the following wait_event. And make sure, wake_up is called in case of an i/o error on the qdio-device. Signed-off-by: Ursula Braun Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/qdio.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 445cf364e46..17df222dea8 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -2082,7 +2082,6 @@ qdio_timeout_handler(struct ccw_device *cdev) default: BUG(); } - ccw_device_set_timeout(cdev, 0); wake_up(&cdev->private->wait_q); } @@ -2121,6 +2120,8 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *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); @@ -2667,12 +2668,12 @@ qdio_shutdown(struct ccw_device *cdev, int how) spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); } else if (rc == 0) { qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); - ccw_device_set_timeout(cdev, timeout); spin_unlock_irqrestore(get_ccwdev_lock(cdev),flags); - wait_event(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_INACTIVE || - irq_ptr->state == QDIO_IRQ_STATE_ERR); + 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); @@ -2692,7 +2693,6 @@ qdio_shutdown(struct ccw_device *cdev, int how) /* Ignore errors. */ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); - ccw_device_set_timeout(cdev, 0); out: up(&irq_ptr->setting_up_sema); return result; @@ -2907,13 +2907,10 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat) QDIO_DBF_TEXT0(0,setup,dbf_text); QDIO_DBF_TEXT0(0,trace,dbf_text); - if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat)) { - ccw_device_set_timeout(cdev, 0); + if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat)) return; - } qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED); - ccw_device_set_timeout(cdev, 0); } int @@ -3196,8 +3193,6 @@ qdio_establish(struct qdio_initialize *init_data) irq_ptr->schid.ssid, irq_ptr->schid.sch_no, result, result2); result=result2; - if (result) - ccw_device_set_timeout(cdev, 0); } spin_unlock_irqrestore(get_ccwdev_lock(cdev),saveflags); @@ -3279,7 +3274,6 @@ qdio_activate(struct ccw_device *cdev, int flags) spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); - ccw_device_set_timeout(cdev, 0); ccw_device_set_options(cdev, CCWDEV_REPORT_ALL); result=ccw_device_start(cdev,&irq_ptr->ccw,QDIO_DOING_ACTIVATE, 0, DOIO_DENY_PREFETCH); -- GitLab From 887d935a84df41f154508821c6b7d96de7dc2c41 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:57:26 +0200 Subject: [PATCH 1746/2509] [S390] sclp: keep facility mask up to date. In case the supported sclp facilities change the new mask should be saved. Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 2c7a1ee6b04..277f9ccfbb7 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -506,6 +506,8 @@ sclp_state_change_cb(struct evbuf_header *evbuf) if (scbuf->validity_sclp_send_mask) sclp_send_mask = scbuf->sclp_send_mask; spin_unlock_irqrestore(&sclp_lock, flags); + if (scbuf->validity_sclp_active_facility_mask) + sclp_facilities = scbuf->sclp_active_facility_mask; sclp_dispatch_state_change(); } -- GitLab From 0c3252d58c54c87ee0f8f40d840e0146a3b1d5fd Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 14 Jul 2008 09:57:27 +0200 Subject: [PATCH 1747/2509] [S390] make appldata compile w/o CONFIG_SWAP Avoid compile error by using EXPORT_SYMBOL_GPL(si_swapinfo) only if CONFIG_SWAP is set. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/appldata/appldata_base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index ad40729bec3..803f3645edf 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -584,7 +584,9 @@ EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); EXPORT_SYMBOL_GPL(appldata_diag); +#ifdef CONFIG_SWAP EXPORT_SYMBOL_GPL(si_swapinfo); +#endif EXPORT_SYMBOL_GPL(nr_threads); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); -- GitLab From b9732ca1cb2c18129d2f984b8de02db141b7b830 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:57:28 +0200 Subject: [PATCH 1748/2509] [S390] sclp: fix possible deadlock on cpu rescan. smp_rescan_cpus() calls get_online_cpus() from a multithreaded workqueue context. This may deadlock. This is the same bug as in arch/s390/kernel/topology.c. This patch can be reverted as soon as Oleg's patch gets merged. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_config.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index ad05a87bc48..7c9b39cee59 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -40,9 +41,19 @@ static void sclp_cpu_capability_notify(struct work_struct *work) put_online_cpus(); } -static void __ref sclp_cpu_change_notify(struct work_struct *work) +static int sclp_cpu_kthread(void *data) { smp_rescan_cpus(); + return 0; +} + +static void __ref sclp_cpu_change_notify(struct work_struct *work) +{ + /* Can't call smp_rescan_cpus() from workqueue context since it may + * deadlock in case of cpu hotplug. So we have to create a kernel + * thread in order to call it. + */ + kthread_run(sclp_cpu_kthread, NULL, "cpu_rescan"); } static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) -- GitLab From b4a33acb690525c5ca37e177f5cd26c62d3ef976 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:57:29 +0200 Subject: [PATCH 1749/2509] [S390] Remove ipldelay kernel parameter. Using the ipldelay kernel parameter leads to a crash at IPL time. Since this is broken since a long time it looks like nobody is using it anymore. So remove it instead of fixing it. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2bc70b6e876..b91caadf974 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -289,32 +289,6 @@ static int __init early_parse_mem(char *p) } early_param("mem", early_parse_mem); -/* - * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes - */ -static int __init early_parse_ipldelay(char *p) -{ - unsigned long delay = 0; - - delay = simple_strtoul(p, &p, 0); - - switch (*p) { - case 's': - case 'S': - delay *= 1000000; - break; - case 'm': - case 'M': - delay *= 60 * 1000000; - } - - /* now wait for the requested amount of time */ - udelay(delay); - - return 0; -} -early_param("ipldelay", early_parse_ipldelay); - #ifdef CONFIG_S390_SWITCH_AMODE #ifdef CONFIG_PGSTE unsigned int switch_amode = 1; -- GitLab From 0ae7a7b250bdf7ee87c8346164ef3c47fb79dfbd Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:43 +0200 Subject: [PATCH 1750/2509] [S390] cio: Register all subchannels. Register all valid subchannels, not only I/O subchannels. Move I/O subchannel specific initialization to io_subchannel_probe(). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.h | 1 + drivers/s390/cio/cio.c | 126 +++++++++++++++----------------------- drivers/s390/cio/css.c | 19 ------ drivers/s390/cio/css.h | 2 - drivers/s390/cio/device.c | 38 ++++++++++-- 5 files changed, 85 insertions(+), 101 deletions(-) diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 65286563c59..59c2fc069d9 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -12,6 +12,7 @@ #include #include #include "chsc.h" +#include "css.h" #define CHP_STATUS_STANDBY 0 #define CHP_STATUS_CONFIGURED 1 diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 7b5969ed05c..903e23ae8ed 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -2,7 +2,7 @@ * drivers/s390/cio/cio.c * S/390 common I/O routines -- low level i/o calls * - * Copyright (C) IBM Corp. 1999,2006 + * Copyright IBM Corp. 1999,2008 * Author(s): Ingo Adlung (adlung@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) * Arnd Bergmann (arndb@de.ibm.com) @@ -494,27 +494,46 @@ int cio_create_sch_lock(struct subchannel *sch) return 0; } -/* - * cio_validate_subchannel() +static int cio_validate_io_subchannel(struct subchannel *sch) +{ + /* Initialization for io subchannels. */ + if (!css_sch_is_valid(&sch->schib)) + return -ENODEV; + + /* Devno is valid. */ + if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { + /* + * This device must not be known to Linux. So we simply + * say that there is no device and return ENODEV. + */ + CIO_MSG_EVENT(6, "Blacklisted device detected " + "at devno %04X, subchannel set %x\n", + sch->schib.pmcw.dev, sch->schid.ssid); + return -ENODEV; + } + return 0; +} + +/** + * cio_validate_subchannel - basic validation of subchannel + * @sch: subchannel structure to be filled out + * @schid: subchannel id * * Find out subchannel type and initialize struct subchannel. * Return codes: - * SUBCHANNEL_TYPE_IO for a normal io subchannel - * SUBCHANNEL_TYPE_CHSC for a chsc subchannel - * SUBCHANNEL_TYPE_MESSAGE for a messaging subchannel - * SUBCHANNEL_TYPE_ADM for a adm(?) subchannel + * 0 on success * -ENXIO for non-defined subchannels - * -ENODEV for subchannels with invalid device number or blacklisted devices + * -ENODEV for invalid subchannels or blacklisted devices + * -EIO for subchannels in an invalid subchannel set */ -int -cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) +int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) { char dbf_txt[15]; int ccode; int err; - sprintf (dbf_txt, "valsch%x", schid.sch_no); - CIO_TRACE_EVENT (4, dbf_txt); + sprintf(dbf_txt, "valsch%x", schid.sch_no); + CIO_TRACE_EVENT(4, dbf_txt); /* Nuke all fields. */ memset(sch, 0, sizeof(struct subchannel)); @@ -545,68 +564,18 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) } /* Copy subchannel type from path management control word. */ sch->st = sch->schib.pmcw.st; - - /* - * ... just being curious we check for non I/O subchannels - */ - if (sch->st != 0) { - CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports " - "non-I/O subchannel type %04X\n", - sch->schid.ssid, sch->schid.sch_no, sch->st); - /* We stop here for non-io subchannels. */ - err = sch->st; - goto out; + switch (sch->st) { + case SUBCHANNEL_TYPE_IO: + err = cio_validate_io_subchannel(sch); + break; + default: + err = 0; } - - /* Initialization for io subchannels. */ - if (!css_sch_is_valid(&sch->schib)) { - err = -ENODEV; + if (err) goto out; - } - /* Devno is valid. */ - if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { - /* - * This device must not be known to Linux. So we simply - * say that there is no device and return ENODEV. - */ - CIO_MSG_EVENT(6, "Blacklisted device detected " - "at devno %04X, subchannel set %x\n", - sch->schib.pmcw.dev, sch->schid.ssid); - err = -ENODEV; - goto out; - } - if (cio_is_console(sch->schid)) { - sch->opm = 0xff; - sch->isc = 1; - } else { - sch->opm = chp_get_sch_opm(sch); - sch->isc = 3; - } - sch->lpm = sch->schib.pmcw.pam & sch->opm; - - CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " - "- PIM = %02X, PAM = %02X, POM = %02X\n", - sch->schib.pmcw.dev, sch->schid.ssid, - sch->schid.sch_no, sch->schib.pmcw.pim, - sch->schib.pmcw.pam, sch->schib.pmcw.pom); - - /* - * We now have to initially ... - * ... enable "concurrent sense" - * ... enable "multipath mode" if more than one - * CHPID is available. This is done regardless - * whether multiple paths are available for us. - */ - sch->schib.pmcw.csense = 1; /* concurrent sense */ - sch->schib.pmcw.ena = 0; - if ((sch->lpm & (sch->lpm - 1)) != 0) - sch->schib.pmcw.mp = 1; /* multipath mode */ - /* clean up possible residual cmf stuff */ - sch->schib.pmcw.mme = 0; - sch->schib.pmcw.mbfc = 0; - sch->schib.pmcw.mbi = 0; - sch->schib.mba = 0; + CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n", + sch->schid.ssid, sch->schid.sch_no, sch->st); return 0; out: if (!cio_is_console(schid)) @@ -793,7 +762,6 @@ cio_probe_console(void) * enable console I/O-interrupt subclass 1 */ ctl_set_bit(6, 30); - console_subchannel.isc = 1; console_subchannel.schib.pmcw.isc = 1; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; @@ -864,7 +832,7 @@ static void udelay_reset(unsigned long usecs) } static int -__clear_subchannel_easy(struct subchannel_id schid) +__clear_io_subchannel_easy(struct subchannel_id schid) { int retry; @@ -921,11 +889,19 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) case -ENODEV: break; default: /* -EBUSY */ - if (__clear_subchannel_easy(schid)) - break; /* give up... */ + switch (schib.pmcw.st) { + case SUBCHANNEL_TYPE_IO: + if (__clear_io_subchannel_easy(schid)) + goto out; /* give up... */ + break; + default: + /* No default clear strategy */ + break; + } stsch(schid, &schib); __disable_subchannel_easy(schid, &schib); } +out: return 0; } diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index a76956512b2..b7f4b52c5a9 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -121,25 +121,6 @@ css_alloc_subchannel(struct subchannel_id schid) kfree(sch); return ERR_PTR(ret); } - - if (sch->st != SUBCHANNEL_TYPE_IO) { - /* For now we ignore all non-io subchannels. */ - kfree(sch); - return ERR_PTR(-EINVAL); - } - - /* - * Set intparm to subchannel address. - * This is fine even on 64bit since the subchannel is always located - * under 2G. - */ - sch->schib.pmcw.intparm = (u32)(addr_t)sch; - ret = cio_modify(sch); - if (ret) { - kfree(sch->lock); - kfree(sch); - return ERR_PTR(ret); - } return sch; } diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index e1913518f35..bfe0ada43f2 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -60,8 +60,6 @@ struct pgid { /* * A css driver handles all subchannels of one type. - * Currently, we only care about I/O subchannels (type 0), these - * have a ccw_device connected to them. */ struct subchannel; struct css_driver { diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e22813db74a..0ed5a81260b 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -24,6 +24,7 @@ #include /* HZ */ #include +#include "chp.h" #include "cio.h" #include "cio_debug.h" #include "css.h" @@ -1037,7 +1038,6 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) struct ccw_device_private *priv; sch_set_cdev(sch, cdev); - sch->driver = &io_subchannel_driver; cdev->ccwlock = sch->lock; /* Init private data. */ @@ -1122,8 +1122,33 @@ static void io_subchannel_irq(struct subchannel *sch) dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); } -static int -io_subchannel_probe (struct subchannel *sch) +static void io_subchannel_init_fields(struct subchannel *sch) +{ + if (cio_is_console(sch->schid)) + sch->opm = 0xff; + else + sch->opm = chp_get_sch_opm(sch); + sch->lpm = sch->schib.pmcw.pam & sch->opm; + sch->isc = cio_is_console(sch->schid) ? 1 : 3; + + CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X" + " - PIM = %02X, PAM = %02X, POM = %02X\n", + sch->schib.pmcw.dev, sch->schid.ssid, + sch->schid.sch_no, sch->schib.pmcw.pim, + sch->schib.pmcw.pam, sch->schib.pmcw.pom); + /* Initially set up some fields in the pmcw. */ + sch->schib.pmcw.ena = 0; + sch->schib.pmcw.csense = 1; /* concurrent sense */ + if ((sch->lpm & (sch->lpm - 1)) != 0) + sch->schib.pmcw.mp = 1; /* multipath mode */ + /* clean up possible residual cmf stuff */ + sch->schib.pmcw.mme = 0; + sch->schib.pmcw.mbfc = 0; + sch->schib.pmcw.mbi = 0; + sch->schib.mba = 0; +} + +static int io_subchannel_probe(struct subchannel *sch) { struct ccw_device *cdev; int rc; @@ -1152,6 +1177,7 @@ io_subchannel_probe (struct subchannel *sch) get_device(&cdev->dev); return 0; } + io_subchannel_init_fields(sch); /* * First check if a fitting device may be found amongst the * disconnected devices or in the orphanage. @@ -1297,14 +1323,16 @@ spinlock_t * cio_get_console_lock(void) return &ccw_console_lock; } -static int -ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch) +static int ccw_device_console_enable(struct ccw_device *cdev, + struct subchannel *sch) { int rc; /* Attach subchannel private data. */ sch->private = cio_get_console_priv(); memset(sch->private, 0, sizeof(struct io_subchannel_private)); + io_subchannel_init_fields(sch); + sch->driver = &io_subchannel_driver; /* Initialize the ccw_device structure. */ cdev->dev.parent= &sch->dev; rc = io_subchannel_recog(cdev, sch); -- GitLab From 7e9db9eaefdb8798730790214ff1b7746006ec98 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:44 +0200 Subject: [PATCH 1751/2509] [S390] cio: Introduce modalias for css bus. Add modalias and subchannel type attributes for all subchannels. I/O subchannel specific attributes are now created in io_subchannel_probe(). modalias and subchannel type are also added to the uevent for the css bus. Also make the css modalias known. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- Documentation/ABI/testing/sysfs-bus-css | 35 +++++++++++++ drivers/s390/cio/cio.h | 1 + drivers/s390/cio/css.c | 69 ++++++++++++++++++++++--- drivers/s390/cio/css.h | 2 - drivers/s390/cio/device.c | 47 +++++++++++------ include/linux/mod_devicetable.h | 9 ++++ scripts/mod/file2alias.c | 12 +++++ 7 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-css diff --git a/Documentation/ABI/testing/sysfs-bus-css b/Documentation/ABI/testing/sysfs-bus-css new file mode 100644 index 00000000000..b585ec258a0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-css @@ -0,0 +1,35 @@ +What: /sys/bus/css/devices/.../type +Date: March 2008 +Contact: Cornelia Huck + linux-s390@vger.kernel.org +Description: Contains the subchannel type, as reported by the hardware. + This attribute is present for all subchannel types. + +What: /sys/bus/css/devices/.../modalias +Date: March 2008 +Contact: Cornelia Huck + linux-s390@vger.kernel.org +Description: Contains the module alias as reported with uevents. + It is of the format css:t and present for all + subchannel types. + +What: /sys/bus/css/drivers/io_subchannel/.../chpids +Date: December 2002 +Contact: Cornelia Huck + linux-s390@vger.kernel.org +Description: Contains the ids of the channel paths used by this + subchannel, as reported by the channel subsystem + during subchannel recognition. + Note: This is an I/O-subchannel specific attribute. +Users: s390-tools, HAL + +What: /sys/bus/css/drivers/io_subchannel/.../pimpampom +Date: December 2002 +Contact: Cornelia Huck + linux-s390@vger.kernel.org +Description: Contains the PIM/PAM/POM values, as reported by the + channel subsystem when last queried by the common I/O + layer (this implies that this attribute is not neccessarily + in sync with the values current in the channel subsystem). + Note: This is an I/O-subchannel specific attribute. +Users: s390-tools, HAL diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 6e933aebe01..4062748e834 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "chsc.h" #include "schid.h" diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index b7f4b52c5a9..53e7496dc90 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -2,8 +2,7 @@ * drivers/s390/cio/css.c * driver for channel subsystem * - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, - * IBM Corporation + * Copyright IBM Corp. 2002,2008 * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) */ @@ -210,6 +209,41 @@ void css_update_ssd_info(struct subchannel *sch) } } +static ssize_t type_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct subchannel *sch = to_subchannel(dev); + + return sprintf(buf, "%01x\n", sch->st); +} + +static DEVICE_ATTR(type, 0444, type_show, NULL); + +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct subchannel *sch = to_subchannel(dev); + + return sprintf(buf, "css:t%01X\n", sch->st); +} + +static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); + +static struct attribute *subch_attrs[] = { + &dev_attr_type.attr, + &dev_attr_modalias.attr, + NULL, +}; + +static struct attribute_group subch_attr_group = { + .attrs = subch_attrs, +}; + +static struct attribute_group *default_subch_attr_groups[] = { + &subch_attr_group, + NULL, +}; + static int css_register_subchannel(struct subchannel *sch) { int ret; @@ -218,16 +252,17 @@ static int css_register_subchannel(struct subchannel *sch) sch->dev.parent = &channel_subsystems[0]->device; sch->dev.bus = &css_bus_type; sch->dev.release = &css_subchannel_release; - sch->dev.groups = subch_attr_groups; + sch->dev.groups = default_subch_attr_groups; /* * We don't want to generate uevents for I/O subchannels that don't * have a working ccw device behind them since they will be * unregistered before they can be used anyway, so we delay the add * uevent until after device recognition was successful. + * Note that we suppress the uevent for all subchannel types; + * the subchannel driver can decide itself when it wants to inform + * userspace of its existence. */ - if (!cio_is_console(sch->schid)) - /* Console is special, no need to suppress. */ - sch->dev.uevent_suppress = 1; + sch->dev.uevent_suppress = 1; css_update_ssd_info(sch); /* make it known to the system */ ret = css_sch_device_register(sch); @@ -236,6 +271,15 @@ static int css_register_subchannel(struct subchannel *sch) sch->schid.ssid, sch->schid.sch_no, ret); return ret; } + if (!sch->driver) { + /* + * No driver matched. Generate the uevent now so that + * a fitting driver module may be loaded based on the + * modalias. + */ + sch->dev.uevent_suppress = 0; + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } return ret; } @@ -926,12 +970,25 @@ static void css_shutdown(struct device *dev) sch->driver->shutdown(sch); } +static int css_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct subchannel *sch = to_subchannel(dev); + int ret; + + ret = add_uevent_var(env, "ST=%01X", sch->st); + if (ret) + return ret; + ret = add_uevent_var(env, "MODALIAS=css:t%01X", sch->st); + return ret; +} + struct bus_type css_bus_type = { .name = "css", .match = css_bus_match, .probe = css_probe, .remove = css_remove, .shutdown = css_shutdown, + .uevent = css_uevent, }; /** diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index bfe0ada43f2..e0fc7b49978 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -143,6 +143,4 @@ int css_sch_is_valid(struct schib *); extern struct workqueue_struct *slow_path_wq; void css_wait_for_slow_path(void); - -extern struct attribute_group *subch_attr_groups[]; #endif diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 0ed5a81260b..23b129fd4d8 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -585,19 +585,14 @@ static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); static DEVICE_ATTR(online, 0644, online_show, online_store); static DEVICE_ATTR(availability, 0444, available_show, NULL); -static struct attribute * subch_attrs[] = { +static struct attribute *io_subchannel_attrs[] = { &dev_attr_chpids.attr, &dev_attr_pimpampom.attr, NULL, }; -static struct attribute_group subch_attr_group = { - .attrs = subch_attrs, -}; - -struct attribute_group *subch_attr_groups[] = { - &subch_attr_group, - NULL, +static struct attribute_group io_subchannel_attr_group = { + .attrs = io_subchannel_attrs, }; static struct attribute * ccwdev_attrs[] = { @@ -1157,11 +1152,21 @@ static int io_subchannel_probe(struct subchannel *sch) cdev = sch_get_cdev(sch); if (cdev) { + rc = sysfs_create_group(&sch->dev.kobj, + &io_subchannel_attr_group); + if (rc) + CIO_MSG_EVENT(0, "Failed to create io subchannel " + "attributes for subchannel " + "0.%x.%04x (rc=%d)\n", + sch->schid.ssid, sch->schid.sch_no, rc); /* * This subchannel already has an associated ccw_device. - * Register it and exit. This happens for all early - * device, e.g. the console. + * Throw the delayed uevent for the subchannel, register + * the ccw_device and exit. This happens for all early + * devices, e.g. the console. */ + sch->dev.uevent_suppress = 0; + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); cdev->dev.groups = ccwdev_attr_groups; device_initialize(&cdev->dev); ccw_device_register(cdev); @@ -1184,11 +1189,17 @@ static int io_subchannel_probe(struct subchannel *sch) */ dev_id.devno = sch->schib.pmcw.dev; dev_id.ssid = sch->schid.ssid; + rc = sysfs_create_group(&sch->dev.kobj, + &io_subchannel_attr_group); + if (rc) + return rc; /* Allocate I/O subchannel private data. */ sch->private = kzalloc(sizeof(struct io_subchannel_private), GFP_KERNEL | GFP_DMA); - if (!sch->private) - return -ENOMEM; + if (!sch->private) { + rc = -ENOMEM; + goto out_err; + } cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); if (!cdev) cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), @@ -1207,8 +1218,8 @@ static int io_subchannel_probe(struct subchannel *sch) } cdev = io_subchannel_create_ccwdev(sch); if (IS_ERR(cdev)) { - kfree(sch->private); - return PTR_ERR(cdev); + rc = PTR_ERR(cdev); + goto out_err; } rc = io_subchannel_recog(cdev, sch); if (rc) { @@ -1217,9 +1228,12 @@ static int io_subchannel_probe(struct subchannel *sch) spin_unlock_irqrestore(sch->lock, flags); if (cdev->dev.release) cdev->dev.release(&cdev->dev); - kfree(sch->private); + goto out_err; } - + return 0; +out_err: + kfree(sch->private); + sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); return rc; } @@ -1240,6 +1254,7 @@ io_subchannel_remove (struct subchannel *sch) ccw_device_unregister(cdev); put_device(&cdev->dev); kfree(sch->private); + sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); return 0; } diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 69b2342d5eb..1fd03e732e0 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -159,6 +159,15 @@ struct ap_device_id { #define AP_DEVICE_ID_MATCH_DEVICE_TYPE 0x01 +/* s390 css bus devices (subchannels) */ +struct css_device_id { + __u8 type; /* subchannel type */ + __u8 pad1; + __u16 pad2; + __u32 pad3; + kernel_ulong_t driver_data; +}; + #define ACPI_ID_LEN 16 /* only 9 bytes needed here, 16 bytes are used */ /* to workaround crosscompile issues */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cea4a790e1e..37d5c363fbc 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -304,6 +304,14 @@ static int do_ap_entry(const char *filename, return 1; } +/* looks like: "css:tN" */ +static int do_css_entry(const char *filename, + struct css_device_id *id, char *alias) +{ + sprintf(alias, "css:t%01X", id->type); + return 1; +} + /* Looks like: "serio:tyNprNidNexN" */ static int do_serio_entry(const char *filename, struct serio_device_id *id, char *alias) @@ -680,6 +688,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct ap_device_id), "ap", do_ap_entry, mod); + else if (sym_is(symname, "__mod_css_device_table")) + do_table(symval, sym->st_size, + sizeof(struct css_device_id), "css", + do_css_entry, mod); else if (sym_is(symname, "__mod_serio_device_table")) do_table(symval, sym->st_size, sizeof(struct serio_device_id), "serio", -- GitLab From c820de39bd083222f5be2563181c87493e436f7c Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:45 +0200 Subject: [PATCH 1752/2509] [S390] cio: Rework css driver. Rework the css driver methods to provide sane callbacks for subchannels of all types. As a bonus, this cleans up and simplyfies the machine check handling for I/O subchannels a lot. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 20 ++ drivers/s390/cio/chp.h | 13 +- drivers/s390/cio/chsc.c | 218 ++------------------ drivers/s390/cio/cio.c | 1 + drivers/s390/cio/css.c | 123 ++---------- drivers/s390/cio/css.h | 38 ++-- drivers/s390/cio/device.c | 365 ++++++++++++++++++++++++++-------- drivers/s390/cio/device.h | 7 +- drivers/s390/cio/device_fsm.c | 106 ++-------- 9 files changed, 381 insertions(+), 510 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 297cdceb0ca..297f1653b52 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -496,6 +496,26 @@ void chp_process_crw(int id, int status) chsc_chp_offline(chpid); } +int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) +{ + int i; + int mask; + + for (i = 0; i < 8; i++) { + mask = 0x80 >> i; + if (!(ssd->path_mask & mask)) + continue; + if (!chp_id_is_equal(&ssd->chpid[i], &data->chpid)) + continue; + if ((ssd->fla_valid_mask & mask) && + ((ssd->fla[i] & data->fla_mask) != data->fla)) + continue; + return mask; + } + return 0; +} +EXPORT_SYMBOL_GPL(chp_ssd_get_mask); + static inline int info_bit_num(struct chp_id id) { return id.id + id.cssid * (__MAX_CHPID + 1); diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 59c2fc069d9..f03b0d2cdc0 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -19,6 +19,17 @@ #define CHP_STATUS_RESERVED 2 #define CHP_STATUS_NOT_RECOGNIZED 3 +#define CHP_ONLINE 0 +#define CHP_OFFLINE 1 +#define CHP_VARY_ON 2 +#define CHP_VARY_OFF 3 + +struct res_acc_data { + struct chp_id chpid; + u32 fla_mask; + u16 fla; +}; + static inline int chp_test_bit(u8 *bitmap, int num) { int byte = num >> 3; @@ -50,5 +61,5 @@ int chp_new(struct chp_id chpid); void chp_cfg_schedule(struct chp_id chpid, int configure); void chp_cfg_cancel_deconfigure(struct chp_id chpid); int chp_info_get_status(struct chp_id chpid); - +int chp_ssd_get_mask(struct chsc_ssd_info *, struct res_acc_data *); #endif /* S390_CHP_H */ diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 5de86908b0d..1c0f5db94c7 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -2,8 +2,7 @@ * drivers/s390/cio/chsc.c * S/390 common I/O routines -- channel subsystem call * - * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, - * IBM Corporation + * Copyright IBM Corp. 1999,2008 * Author(s): Ingo Adlung (adlung@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) * Arnd Bergmann (arndb@de.ibm.com) @@ -127,77 +126,12 @@ out_free: return ret; } -static int check_for_io_on_path(struct subchannel *sch, int mask) -{ - int cc; - - cc = stsch(sch->schid, &sch->schib); - if (cc) - return 0; - if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == mask) - return 1; - return 0; -} - -static void terminate_internal_io(struct subchannel *sch) -{ - if (cio_clear(sch)) { - /* Recheck device in case clear failed. */ - sch->lpm = 0; - if (device_trigger_verify(sch) != 0) - css_schedule_eval(sch->schid); - return; - } - /* Request retry of internal operation. */ - device_set_intretry(sch); - /* Call handler. */ - if (sch->driver && sch->driver->termination) - sch->driver->termination(sch); -} - static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) { - int j; - int mask; - struct chp_id *chpid = data; - struct schib schib; - - for (j = 0; j < 8; j++) { - mask = 0x80 >> j; - if ((sch->schib.pmcw.pim & mask) && - (sch->schib.pmcw.chpid[j] == chpid->id)) - break; - } - if (j >= 8) - return 0; - spin_lock_irq(sch->lock); - - stsch(sch->schid, &schib); - if (!css_sch_is_valid(&schib)) - goto out_unreg; - memcpy(&sch->schib, &schib, sizeof(struct schib)); - /* Check for single path devices. */ - if (sch->schib.pmcw.pim == 0x80) - goto out_unreg; - - if (check_for_io_on_path(sch, mask)) { - if (device_is_online(sch)) - device_kill_io(sch); - else { - terminate_internal_io(sch); - /* Re-start path verification. */ - if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - } - } else { - /* trigger path verification. */ - if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - else if (sch->lpm == mask) + if (sch->driver && sch->driver->chp_event) + if (sch->driver->chp_event(sch, data, CHP_OFFLINE) != 0) goto out_unreg; - } - spin_unlock_irq(sch->lock); return 0; @@ -242,53 +176,11 @@ static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) return 0; } -struct res_acc_data { - struct chp_id chpid; - u32 fla_mask; - u16 fla; -}; - -static int get_res_chpid_mask(struct chsc_ssd_info *ssd, - struct res_acc_data *data) -{ - int i; - int mask; - - for (i = 0; i < 8; i++) { - mask = 0x80 >> i; - if (!(ssd->path_mask & mask)) - continue; - if (!chp_id_is_equal(&ssd->chpid[i], &data->chpid)) - continue; - if ((ssd->fla_valid_mask & mask) && - ((ssd->fla[i] & data->fla_mask) != data->fla)) - continue; - return mask; - } - return 0; -} - static int __s390_process_res_acc(struct subchannel *sch, void *data) { - int chp_mask, old_lpm; - struct res_acc_data *res_data = data; - spin_lock_irq(sch->lock); - chp_mask = get_res_chpid_mask(&sch->ssd_info, res_data); - if (chp_mask == 0) - goto out; - if (stsch(sch->schid, &sch->schib)) - goto out; - old_lpm = sch->lpm; - sch->lpm = ((sch->schib.pmcw.pim & - sch->schib.pmcw.pam & - sch->schib.pmcw.pom) - | chp_mask) & sch->opm; - if (!old_lpm && sch->lpm) - device_trigger_reprobe(sch); - else if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); -out: + if (sch->driver && sch->driver->chp_event) + sch->driver->chp_event(sch, data, CHP_ONLINE); spin_unlock_irq(sch->lock); return 0; @@ -509,114 +401,36 @@ void chsc_process_crw(void) } while (sei_area->flags & 0x80); } -static int __chp_add_new_sch(struct subchannel_id schid, void *data) -{ - struct schib schib; - - if (stsch_err(schid, &schib)) - /* We're through */ - return -ENXIO; - - /* Put it on the slow path. */ - css_schedule_eval(schid); - return 0; -} - - -static int __chp_add(struct subchannel *sch, void *data) -{ - int i, mask; - struct chp_id *chpid = data; - - spin_lock_irq(sch->lock); - for (i=0; i<8; i++) { - mask = 0x80 >> i; - if ((sch->schib.pmcw.pim & mask) && - (sch->schib.pmcw.chpid[i] == chpid->id)) - break; - } - if (i==8) { - spin_unlock_irq(sch->lock); - return 0; - } - if (stsch(sch->schid, &sch->schib)) { - spin_unlock_irq(sch->lock); - css_schedule_eval(sch->schid); - return 0; - } - sch->lpm = ((sch->schib.pmcw.pim & - sch->schib.pmcw.pam & - sch->schib.pmcw.pom) - | mask) & sch->opm; - - if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - - spin_unlock_irq(sch->lock); - - return 0; -} - void chsc_chp_online(struct chp_id chpid) { char dbf_txt[15]; + struct res_acc_data res_data; sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) != 0) { + memset(&res_data, 0, sizeof(struct res_acc_data)); + res_data.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); - for_each_subchannel_staged(__chp_add, __chp_add_new_sch, - &chpid); + for_each_subchannel_staged(__s390_process_res_acc, NULL, + &res_data); } } static void __s390_subchannel_vary_chpid(struct subchannel *sch, struct chp_id chpid, int on) { - int chp, old_lpm; - int mask; unsigned long flags; + struct res_acc_data res_data; + memset(&res_data, 0, sizeof(struct res_acc_data)); + res_data.chpid = chpid; spin_lock_irqsave(sch->lock, flags); - old_lpm = sch->lpm; - for (chp = 0; chp < 8; chp++) { - mask = 0x80 >> chp; - if (!(sch->ssd_info.path_mask & mask)) - continue; - if (!chp_id_is_equal(&sch->ssd_info.chpid[chp], &chpid)) - continue; - - if (on) { - sch->opm |= mask; - sch->lpm |= mask; - if (!old_lpm) - device_trigger_reprobe(sch); - else if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - break; - } - sch->opm &= ~mask; - sch->lpm &= ~mask; - if (check_for_io_on_path(sch, mask)) { - if (device_is_online(sch)) - /* Path verification is done after killing. */ - device_kill_io(sch); - else { - /* Kill and retry internal I/O. */ - terminate_internal_io(sch); - /* Re-start path verification. */ - if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - } - } else if (!sch->lpm) { - if (device_trigger_verify(sch) != 0) - css_schedule_eval(sch->schid); - } else if (sch->driver && sch->driver->verify) - sch->driver->verify(sch); - break; - } + if (sch->driver && sch->driver->chp_event) + sch->driver->chp_event(sch, &res_data, + on ? CHP_VARY_ON : CHP_VARY_OFF); spin_unlock_irqrestore(sch->lock, flags); } diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 903e23ae8ed..fdb164f3610 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -564,6 +564,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) } /* Copy subchannel type from path management control word. */ sch->st = sch->schib.pmcw.st; + switch (sch->st) { case SUBCHANNEL_TYPE_IO: err = cio_validate_io_subchannel(sch); diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 53e7496dc90..020566571e0 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -283,7 +283,7 @@ static int css_register_subchannel(struct subchannel *sch) return ret; } -static int css_probe_device(struct subchannel_id schid) +int css_probe_device(struct subchannel_id schid) { int ret; struct subchannel *sch; @@ -330,112 +330,6 @@ int css_sch_is_valid(struct schib *schib) } EXPORT_SYMBOL_GPL(css_sch_is_valid); -static int css_get_subchannel_status(struct subchannel *sch) -{ - struct schib schib; - - if (stsch(sch->schid, &schib)) - return CIO_GONE; - if (!css_sch_is_valid(&schib)) - return CIO_GONE; - if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev)) - return CIO_REVALIDATE; - if (!sch->lpm) - return CIO_NO_PATH; - return CIO_OPER; -} - -static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) -{ - int event, ret, disc; - unsigned long flags; - enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action; - - spin_lock_irqsave(sch->lock, flags); - disc = device_is_disconnected(sch); - if (disc && slow) { - /* Disconnected devices are evaluated directly only.*/ - spin_unlock_irqrestore(sch->lock, flags); - return 0; - } - /* No interrupt after machine check - kill pending timers. */ - device_kill_pending_timer(sch); - if (!disc && !slow) { - /* Non-disconnected devices are evaluated on the slow path. */ - spin_unlock_irqrestore(sch->lock, flags); - return -EAGAIN; - } - event = css_get_subchannel_status(sch); - CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n", - sch->schid.ssid, sch->schid.sch_no, event, - disc ? "disconnected" : "normal", - slow ? "slow" : "fast"); - /* Analyze subchannel status. */ - action = NONE; - switch (event) { - case CIO_NO_PATH: - if (disc) { - /* Check if paths have become available. */ - action = REPROBE; - break; - } - /* fall through */ - case CIO_GONE: - /* Prevent unwanted effects when opening lock. */ - cio_disable_subchannel(sch); - device_set_disconnected(sch); - /* Ask driver what to do with device. */ - action = UNREGISTER; - if (sch->driver && sch->driver->notify) { - spin_unlock_irqrestore(sch->lock, flags); - ret = sch->driver->notify(sch, event); - spin_lock_irqsave(sch->lock, flags); - if (ret) - action = NONE; - } - break; - case CIO_REVALIDATE: - /* Device will be removed, so no notify necessary. */ - if (disc) - /* Reprobe because immediate unregister might block. */ - action = REPROBE; - else - action = UNREGISTER_PROBE; - break; - case CIO_OPER: - if (disc) - /* Get device operational again. */ - action = REPROBE; - break; - } - /* Perform action. */ - ret = 0; - switch (action) { - case UNREGISTER: - case UNREGISTER_PROBE: - /* Unregister device (will use subchannel lock). */ - spin_unlock_irqrestore(sch->lock, flags); - css_sch_device_unregister(sch); - spin_lock_irqsave(sch->lock, flags); - - /* Reset intparm to zeroes. */ - sch->schib.pmcw.intparm = 0; - cio_modify(sch); - break; - case REPROBE: - device_trigger_reprobe(sch); - break; - default: - break; - } - spin_unlock_irqrestore(sch->lock, flags); - /* Probe if necessary. */ - if (action == UNREGISTER_PROBE) - ret = css_probe_device(sch->schid); - - return ret; -} - static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) { struct schib schib; @@ -454,6 +348,21 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) return css_probe_device(schid); } +static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) +{ + int ret = 0; + + if (sch->driver) { + if (sch->driver->sch_event) + ret = sch->driver->sch_event(sch, slow); + else + dev_dbg(&sch->dev, + "Got subchannel machine check but " + "no sch_event handler provided.\n"); + } + return ret; +} + static void css_evaluate_subchannel(struct subchannel_id schid, int slow) { struct subchannel *sch; diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index e0fc7b49978..4cdc132c86b 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -58,18 +58,27 @@ struct pgid { __u32 tod_high; /* high word TOD clock */ } __attribute__ ((packed)); -/* - * A css driver handles all subchannels of one type. - */ struct subchannel; +/** + * struct css_driver - device driver for subchannels + * @owner: owning module + * @subchannel_type: subchannel type supported by this driver + * @drv: embedded device driver structure + * @irq: called on interrupts + * @chp_event: called for events affecting a channel path + * @sch_event: called for events affecting the subchannel + * @probe: function called on probe + * @remove: function called on remove + * @shutdown: called at device shutdown + * @name: name of the device driver + */ struct css_driver { struct module *owner; unsigned int subchannel_type; struct device_driver drv; void (*irq)(struct subchannel *); - int (*notify)(struct subchannel *, int); - void (*verify)(struct subchannel *); - void (*termination)(struct subchannel *); + int (*chp_event)(struct subchannel *, void *, int); + int (*sch_event)(struct subchannel *, int); int (*probe)(struct subchannel *); int (*remove)(struct subchannel *); void (*shutdown)(struct subchannel *); @@ -87,7 +96,8 @@ extern int css_driver_register(struct css_driver *); extern void css_driver_unregister(struct css_driver *); extern void css_sch_device_unregister(struct subchannel *); -extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); +extern int css_probe_device(struct subchannel_id); +extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); extern int css_init_done; int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), int (*fn_unknown)(struct subchannel_id, @@ -119,20 +129,6 @@ struct channel_subsystem { extern struct bus_type css_bus_type; extern struct channel_subsystem *channel_subsystems[]; -/* Some helper functions for disconnected state. */ -int device_is_disconnected(struct subchannel *); -void device_set_disconnected(struct subchannel *); -void device_trigger_reprobe(struct subchannel *); - -/* Helper functions for vary on/off. */ -int device_is_online(struct subchannel *); -void device_kill_io(struct subchannel *); -void device_set_intretry(struct subchannel *sch); -int device_trigger_verify(struct subchannel *sch); - -/* Machine check helper function. */ -void device_kill_pending_timer(struct subchannel *); - /* Helper functions to build lists for the slow path. */ void css_schedule_eval(struct subchannel_id schid); void css_schedule_eval_all(void); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 23b129fd4d8..9281b25087a 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -2,8 +2,7 @@ * drivers/s390/cio/device.c * bus driver for ccw devices * - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, - * IBM Corporation + * Copyright IBM Corp. 2002,2008 * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) * Martin Schwidefsky (schwidefsky@de.ibm.com) @@ -126,19 +125,17 @@ struct bus_type ccw_bus_type; static void io_subchannel_irq(struct subchannel *); static int io_subchannel_probe(struct subchannel *); static int io_subchannel_remove(struct subchannel *); -static int io_subchannel_notify(struct subchannel *, int); -static void io_subchannel_verify(struct subchannel *); -static void io_subchannel_ioterm(struct subchannel *); static void io_subchannel_shutdown(struct subchannel *); +static int io_subchannel_sch_event(struct subchannel *, int); +static int io_subchannel_chp_event(struct subchannel *, void *, int); static struct css_driver io_subchannel_driver = { .owner = THIS_MODULE, .subchannel_type = SUBCHANNEL_TYPE_IO, .name = "io_subchannel", .irq = io_subchannel_irq, - .notify = io_subchannel_notify, - .verify = io_subchannel_verify, - .termination = io_subchannel_ioterm, + .sch_event = io_subchannel_sch_event, + .chp_event = io_subchannel_chp_event, .probe = io_subchannel_probe, .remove = io_subchannel_remove, .shutdown = io_subchannel_shutdown, @@ -786,7 +783,7 @@ static void sch_attach_device(struct subchannel *sch, sch_set_cdev(sch, cdev); cdev->private->schid = sch->schid; cdev->ccwlock = sch->lock; - device_trigger_reprobe(sch); + ccw_device_trigger_reprobe(cdev); spin_unlock_irq(sch->lock); } @@ -1265,11 +1262,7 @@ static int io_subchannel_notify(struct subchannel *sch, int event) cdev = sch_get_cdev(sch); if (!cdev) return 0; - if (!cdev->drv) - return 0; - if (!cdev->online) - return 0; - return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0; + return ccw_device_notify(cdev, event); } static void io_subchannel_verify(struct subchannel *sch) @@ -1281,22 +1274,98 @@ static void io_subchannel_verify(struct subchannel *sch) dev_fsm_event(cdev, DEV_EVENT_VERIFY); } -static void io_subchannel_ioterm(struct subchannel *sch) +static int check_for_io_on_path(struct subchannel *sch, int mask) { - struct ccw_device *cdev; + int cc; - cdev = sch_get_cdev(sch); - if (!cdev) - return; - /* Internal I/O will be retried by the interrupt handler. */ - if (cdev->private->flags.intretry) + cc = stsch(sch->schid, &sch->schib); + if (cc) + return 0; + if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == mask) + return 1; + return 0; +} + +static void terminate_internal_io(struct subchannel *sch, + struct ccw_device *cdev) +{ + if (cio_clear(sch)) { + /* Recheck device in case clear failed. */ + sch->lpm = 0; + if (cdev->online) + dev_fsm_event(cdev, DEV_EVENT_VERIFY); + else + css_schedule_eval(sch->schid); return; + } cdev->private->state = DEV_STATE_CLEAR_VERIFY; + /* Request retry of internal operation. */ + cdev->private->flags.intretry = 1; + /* Call handler. */ if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, ERR_PTR(-EIO)); } +static void io_subchannel_terminate_path(struct subchannel *sch, u8 mask) +{ + struct ccw_device *cdev; + + cdev = sch_get_cdev(sch); + if (!cdev) + return; + if (check_for_io_on_path(sch, mask)) { + if (cdev->private->state == DEV_STATE_ONLINE) + ccw_device_kill_io(cdev); + else { + terminate_internal_io(sch, cdev); + /* Re-start path verification. */ + dev_fsm_event(cdev, DEV_EVENT_VERIFY); + } + } else + /* trigger path verification. */ + dev_fsm_event(cdev, DEV_EVENT_VERIFY); + +} + +static int io_subchannel_chp_event(struct subchannel *sch, void *data, + int event) +{ + int mask; + struct res_acc_data *res_data; + + res_data = data; + mask = chp_ssd_get_mask(&sch->ssd_info, res_data); + if (!mask) + return 0; + switch (event) { + case CHP_VARY_OFF: + sch->opm &= ~mask; + sch->lpm &= ~mask; + io_subchannel_terminate_path(sch, mask); + break; + case CHP_VARY_ON: + sch->opm |= mask; + sch->lpm |= mask; + io_subchannel_verify(sch); + break; + case CHP_OFFLINE: + if (stsch(sch->schid, &sch->schib)) + return -ENXIO; + if (!css_sch_is_valid(&sch->schib)) + return -ENODEV; + io_subchannel_terminate_path(sch, mask); + break; + case CHP_ONLINE: + if (stsch(sch->schid, &sch->schib)) + return -ENXIO; + sch->lpm |= mask & sch->opm; + io_subchannel_verify(sch); + break; + } + return 0; +} + static void io_subchannel_shutdown(struct subchannel *sch) { @@ -1326,6 +1395,195 @@ io_subchannel_shutdown(struct subchannel *sch) cio_disable_subchannel(sch); } +static int io_subchannel_get_status(struct subchannel *sch) +{ + struct schib schib; + + if (stsch(sch->schid, &schib) || !schib.pmcw.dnv) + return CIO_GONE; + if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev)) + return CIO_REVALIDATE; + if (!sch->lpm) + return CIO_NO_PATH; + return CIO_OPER; +} + +static int device_is_disconnected(struct ccw_device *cdev) +{ + if (!cdev) + return 0; + return (cdev->private->state == DEV_STATE_DISCONNECTED || + cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID); +} + +static int recovery_check(struct device *dev, void *data) +{ + struct ccw_device *cdev = to_ccwdev(dev); + int *redo = data; + + spin_lock_irq(cdev->ccwlock); + switch (cdev->private->state) { + case DEV_STATE_DISCONNECTED: + CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", + cdev->private->dev_id.ssid, + cdev->private->dev_id.devno); + dev_fsm_event(cdev, DEV_EVENT_VERIFY); + *redo = 1; + break; + case DEV_STATE_DISCONNECTED_SENSE_ID: + *redo = 1; + break; + } + spin_unlock_irq(cdev->ccwlock); + + return 0; +} + +static void recovery_work_func(struct work_struct *unused) +{ + int redo = 0; + + bus_for_each_dev(&ccw_bus_type, NULL, &redo, recovery_check); + if (redo) { + spin_lock_irq(&recovery_lock); + if (!timer_pending(&recovery_timer)) { + if (recovery_phase < ARRAY_SIZE(recovery_delay) - 1) + recovery_phase++; + mod_timer(&recovery_timer, jiffies + + recovery_delay[recovery_phase] * HZ); + } + spin_unlock_irq(&recovery_lock); + } else + CIO_MSG_EVENT(4, "recovery: end\n"); +} + +static DECLARE_WORK(recovery_work, recovery_work_func); + +static void recovery_func(unsigned long data) +{ + /* + * We can't do our recovery in softirq context and it's not + * performance critical, so we schedule it. + */ + schedule_work(&recovery_work); +} + +static void ccw_device_schedule_recovery(void) +{ + unsigned long flags; + + CIO_MSG_EVENT(4, "recovery: schedule\n"); + spin_lock_irqsave(&recovery_lock, flags); + if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { + recovery_phase = 0; + mod_timer(&recovery_timer, jiffies + recovery_delay[0] * HZ); + } + spin_unlock_irqrestore(&recovery_lock, flags); +} + +static void device_set_disconnected(struct ccw_device *cdev) +{ + if (!cdev) + return; + ccw_device_set_timeout(cdev, 0); + cdev->private->flags.fake_irb = 0; + cdev->private->state = DEV_STATE_DISCONNECTED; + if (cdev->online) + ccw_device_schedule_recovery(); +} + +static int io_subchannel_sch_event(struct subchannel *sch, int slow) +{ + int event, ret, disc; + unsigned long flags; + enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action; + struct ccw_device *cdev; + + spin_lock_irqsave(sch->lock, flags); + cdev = sch_get_cdev(sch); + disc = device_is_disconnected(cdev); + if (disc && slow) { + /* Disconnected devices are evaluated directly only.*/ + spin_unlock_irqrestore(sch->lock, flags); + return 0; + } + /* No interrupt after machine check - kill pending timers. */ + if (cdev) + ccw_device_set_timeout(cdev, 0); + if (!disc && !slow) { + /* Non-disconnected devices are evaluated on the slow path. */ + spin_unlock_irqrestore(sch->lock, flags); + return -EAGAIN; + } + event = io_subchannel_get_status(sch); + CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n", + sch->schid.ssid, sch->schid.sch_no, event, + disc ? "disconnected" : "normal", + slow ? "slow" : "fast"); + /* Analyze subchannel status. */ + action = NONE; + switch (event) { + case CIO_NO_PATH: + if (disc) { + /* Check if paths have become available. */ + action = REPROBE; + break; + } + /* fall through */ + case CIO_GONE: + /* Prevent unwanted effects when opening lock. */ + cio_disable_subchannel(sch); + device_set_disconnected(cdev); + /* Ask driver what to do with device. */ + action = UNREGISTER; + spin_unlock_irqrestore(sch->lock, flags); + ret = io_subchannel_notify(sch, event); + spin_lock_irqsave(sch->lock, flags); + if (ret) + action = NONE; + break; + case CIO_REVALIDATE: + /* Device will be removed, so no notify necessary. */ + if (disc) + /* Reprobe because immediate unregister might block. */ + action = REPROBE; + else + action = UNREGISTER_PROBE; + break; + case CIO_OPER: + if (disc) + /* Get device operational again. */ + action = REPROBE; + break; + } + /* Perform action. */ + ret = 0; + switch (action) { + case UNREGISTER: + case UNREGISTER_PROBE: + /* Unregister device (will use subchannel lock). */ + spin_unlock_irqrestore(sch->lock, flags); + css_sch_device_unregister(sch); + spin_lock_irqsave(sch->lock, flags); + + /* Reset intparm to zeroes. */ + sch->schib.pmcw.intparm = 0; + cio_modify(sch); + break; + case REPROBE: + ccw_device_trigger_reprobe(cdev); + break; + default: + break; + } + spin_unlock_irqrestore(sch->lock, flags); + /* Probe if necessary. */ + if (action == UNREGISTER_PROBE) + ret = css_probe_device(sch->schid); + + return ret; +} + #ifdef CONFIG_CCW_CONSOLE static struct ccw_device console_cdev; static struct ccw_device_private console_private; @@ -1558,71 +1816,6 @@ ccw_device_get_subchannel_id(struct ccw_device *cdev) return sch->schid; } -static int recovery_check(struct device *dev, void *data) -{ - struct ccw_device *cdev = to_ccwdev(dev); - int *redo = data; - - spin_lock_irq(cdev->ccwlock); - switch (cdev->private->state) { - case DEV_STATE_DISCONNECTED: - CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno); - dev_fsm_event(cdev, DEV_EVENT_VERIFY); - *redo = 1; - break; - case DEV_STATE_DISCONNECTED_SENSE_ID: - *redo = 1; - break; - } - spin_unlock_irq(cdev->ccwlock); - - return 0; -} - -static void recovery_work_func(struct work_struct *unused) -{ - int redo = 0; - - bus_for_each_dev(&ccw_bus_type, NULL, &redo, recovery_check); - if (redo) { - spin_lock_irq(&recovery_lock); - if (!timer_pending(&recovery_timer)) { - if (recovery_phase < ARRAY_SIZE(recovery_delay) - 1) - recovery_phase++; - mod_timer(&recovery_timer, jiffies + - recovery_delay[recovery_phase] * HZ); - } - spin_unlock_irq(&recovery_lock); - } else - CIO_MSG_EVENT(4, "recovery: end\n"); -} - -static DECLARE_WORK(recovery_work, recovery_work_func); - -static void recovery_func(unsigned long data) -{ - /* - * We can't do our recovery in softirq context and it's not - * performance critical, so we schedule it. - */ - schedule_work(&recovery_work); -} - -void ccw_device_schedule_recovery(void) -{ - unsigned long flags; - - CIO_MSG_EVENT(4, "recovery: schedule\n"); - spin_lock_irqsave(&recovery_lock, flags); - if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { - recovery_phase = 0; - mod_timer(&recovery_timer, jiffies + recovery_delay[0] * HZ); - } - spin_unlock_irqrestore(&recovery_lock, flags); -} - MODULE_LICENSE("GPL"); EXPORT_SYMBOL(ccw_device_set_online); EXPORT_SYMBOL(ccw_device_set_offline); diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index cb08092be39..9800a8335a3 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h @@ -88,8 +88,6 @@ int ccw_device_recognition(struct ccw_device *); int ccw_device_online(struct ccw_device *); int ccw_device_offline(struct ccw_device *); -void ccw_device_schedule_recovery(void); - /* Function prototypes for device status and basic sense stuff. */ void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); void ccw_device_accumulate_basic_sense(struct ccw_device *, struct irb *); @@ -118,6 +116,11 @@ int ccw_device_call_handler(struct ccw_device *); int ccw_device_stlck(struct ccw_device *); +/* Helper function for machine check handling. */ +void ccw_device_trigger_reprobe(struct ccw_device *); +void ccw_device_kill_io(struct ccw_device *); +int ccw_device_notify(struct ccw_device *, int); + /* qdio needs this. */ void ccw_device_set_timeout(struct ccw_device *, int); extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index e268d5a77c1..c9b97cbc220 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -2,8 +2,7 @@ * drivers/s390/cio/device_fsm.c * finite state machine for device handling * - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, - * IBM Corporation + * Copyright IBM Corp. 2002,2008 * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) * Martin Schwidefsky (schwidefsky@de.ibm.com) */ @@ -27,65 +26,6 @@ static int timeout_log_enabled; -int -device_is_online(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev) - return 0; - return (cdev->private->state == DEV_STATE_ONLINE); -} - -int -device_is_disconnected(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev) - return 0; - return (cdev->private->state == DEV_STATE_DISCONNECTED || - cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID); -} - -void -device_set_disconnected(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev) - return; - ccw_device_set_timeout(cdev, 0); - cdev->private->flags.fake_irb = 0; - cdev->private->state = DEV_STATE_DISCONNECTED; - if (cdev->online) - ccw_device_schedule_recovery(); -} - -void device_set_intretry(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev) - return; - cdev->private->flags.intretry = 1; -} - -int device_trigger_verify(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev || !cdev->online) - return -EINVAL; - dev_fsm_event(cdev, DEV_EVENT_VERIFY); - return 0; -} - static int __init ccw_timeout_log_setup(char *unused) { timeout_log_enabled = 1; @@ -171,18 +111,6 @@ ccw_device_set_timeout(struct ccw_device *cdev, int expires) add_timer(&cdev->private->timer); } -/* Kill any pending timers after machine check. */ -void -device_kill_pending_timer(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = sch_get_cdev(sch); - if (!cdev) - return; - ccw_device_set_timeout(cdev, 0); -} - /* * Cancel running i/o. This is called repeatedly since halt/clear are * asynchronous operations. We do one try with cio_cancel, two tries @@ -388,25 +316,27 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err) } } +int ccw_device_notify(struct ccw_device *cdev, int event) +{ + if (!cdev->drv) + return 0; + if (!cdev->online) + return 0; + return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0; +} + static void ccw_device_oper_notify(struct work_struct *work) { struct ccw_device_private *priv; struct ccw_device *cdev; - struct subchannel *sch; int ret; unsigned long flags; priv = container_of(work, struct ccw_device_private, kick_work); cdev = priv->cdev; + ret = ccw_device_notify(cdev, CIO_OPER); spin_lock_irqsave(cdev->ccwlock, flags); - sch = to_subchannel(cdev->dev.parent); - if (sch->driver && sch->driver->notify) { - spin_unlock_irqrestore(cdev->ccwlock, flags); - ret = sch->driver->notify(sch, CIO_OPER); - spin_lock_irqsave(cdev->ccwlock, flags); - } else - ret = 0; if (ret) { /* Reenable channel measurements, if needed. */ spin_unlock_irqrestore(cdev->ccwlock, flags); @@ -986,12 +916,10 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) ERR_PTR(-EIO)); } -void device_kill_io(struct subchannel *sch) +void ccw_device_kill_io(struct ccw_device *cdev) { int ret; - struct ccw_device *cdev; - cdev = sch_get_cdev(sch); ret = ccw_device_cancel_halt_clear(cdev); if (ret == -EBUSY) { ccw_device_set_timeout(cdev, 3*HZ); @@ -1055,17 +983,14 @@ ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event) ccw_device_sense_id_start(cdev); } -void -device_trigger_reprobe(struct subchannel *sch) +void ccw_device_trigger_reprobe(struct ccw_device *cdev) { - struct ccw_device *cdev; + struct subchannel *sch; - cdev = sch_get_cdev(sch); - if (!cdev) - return; if (cdev->private->state != DEV_STATE_DISCONNECTED) return; + sch = to_subchannel(cdev->dev.parent); /* Update some values. */ if (stsch(sch->schid, &sch->schib)) return; @@ -1081,7 +1006,6 @@ device_trigger_reprobe(struct subchannel *sch) sch->schib.pmcw.ena = 0; if ((sch->lpm & (sch->lpm - 1)) != 0) sch->schib.pmcw.mp = 1; - sch->schib.pmcw.intparm = (u32)(addr_t)sch; /* We should also udate ssd info, but this has to wait. */ /* Check if this is another device which appeared on the same sch. */ if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { -- GitLab From c11561897ab57a3c11e0a284ba17795d580589ab Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:46 +0200 Subject: [PATCH 1753/2509] [S390] cio: Cleanup crw interface. Eliminate the need for the machine check handler to call into the common I/O layer directly by introducing an interface to register handlers for crws per rsc. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 49 ++++++++++++++++--- drivers/s390/cio/chp.h | 1 - drivers/s390/cio/chsc.c | 25 ++++++++-- drivers/s390/cio/chsc.h | 2 - drivers/s390/cio/css.c | 31 +++++++++--- drivers/s390/cio/css.h | 1 - drivers/s390/s390mach.c | 102 ++++++++++++++++++---------------------- drivers/s390/s390mach.h | 7 +++ 8 files changed, 140 insertions(+), 78 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 297f1653b52..672d9731c52 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -18,6 +18,7 @@ #include #include +#include "../s390mach.h" #include "cio.h" #include "css.h" #include "ioasm.h" @@ -476,24 +477,52 @@ void *chp_get_chp_desc(struct chp_id chpid) /** * chp_process_crw - process channel-path status change - * @id: channel-path ID number - * @status: non-zero if channel-path has become available, zero otherwise + * @crw0: channel report-word to handler + * @crw1: second channel-report word (always NULL) + * @overflow: crw overflow indication * * Handle channel-report-words indicating that the status of a channel-path * has changed. */ -void chp_process_crw(int id, int status) +static void chp_process_crw(struct crw *crw0, struct crw *crw1, + int overflow) { struct chp_id chpid; + if (overflow) { + css_schedule_eval_all(); + return; + } + CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " + "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", + crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, + crw0->erc, crw0->rsid); + /* + * Check for solicited machine checks. These are + * created by reset channel path and need not be + * handled here. + */ + if (crw0->slct) { + CIO_CRW_EVENT(2, "solicited machine check for " + "channel path %02X\n", crw0->rsid); + return; + } chp_id_init(&chpid); - chpid.id = id; - if (status) { + chpid.id = crw0->rsid; + switch (crw0->erc) { + case CRW_ERC_IPARM: /* Path has come. */ if (!chp_is_registered(chpid)) chp_new(chpid); chsc_chp_online(chpid); - } else + break; + case CRW_ERC_PERRI: /* Path has gone. */ + case CRW_ERC_PERRN: chsc_chp_offline(chpid); + break; + default: + CIO_CRW_EVENT(2, "Don't know how to handle erc=%x\n", + crw0->erc); + } } int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) @@ -674,10 +703,16 @@ static int cfg_wait_idle(void) static int __init chp_init(void) { struct chp_id chpid; + int ret; + ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw); + if (ret) + return ret; chp_wq = create_singlethread_workqueue("cio_chp"); - if (!chp_wq) + if (!chp_wq) { + s390_unregister_crw_handler(CRW_RSC_CPATH); return -ENOMEM; + } INIT_WORK(&cfg_work, cfg_func); init_waitqueue_head(&cfg_wait_queue); if (info_update()) diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index f03b0d2cdc0..dffe2771dda 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -54,7 +54,6 @@ int chp_get_status(struct chp_id chpid); u8 chp_get_sch_opm(struct subchannel *sch); int chp_is_registered(struct chp_id chpid); void *chp_get_chp_desc(struct chp_id chpid); -void chp_process_crw(int id, int available); void chp_remove_cmg_attr(struct channel_path *chp); int chp_add_cmg_attr(struct channel_path *chp); int chp_new(struct chp_id chpid); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 1c0f5db94c7..cb36f792978 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -16,6 +16,7 @@ #include #include +#include "../s390mach.h" #include "css.h" #include "cio.h" #include "cio_debug.h" @@ -372,17 +373,25 @@ static void chsc_process_sei(struct chsc_sei_area *sei_area) } } -void chsc_process_crw(void) +static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) { struct chsc_sei_area *sei_area; + if (overflow) { + css_schedule_eval_all(); + return; + } + CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " + "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", + crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, + crw0->erc, crw0->rsid); if (!sei_page) return; /* Access to sei_page is serialized through machine check handler * thread, so no need for locking. */ sei_area = sei_page; - CIO_TRACE_EVENT( 2, "prcss"); + CIO_TRACE_EVENT(2, "prcss"); do { memset(sei_area, 0, sizeof(*sei_area)); sei_area->request.length = 0x0010; @@ -751,15 +760,23 @@ out: int __init chsc_alloc_sei_area(void) { + int ret; + sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!sei_page) + if (!sei_page) { CIO_MSG_EVENT(0, "Can't allocate page for processing of " "chsc machine checks!\n"); - return (sei_page ? 0 : -ENOMEM); + return -ENOMEM; + } + ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw); + if (ret) + kfree(sei_page); + return ret; } void __init chsc_free_sei_area(void) { + s390_unregister_crw_handler(CRW_RSC_CSS); kfree(sei_page); } diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index d1f5db1e69b..3b7c044d845 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -36,8 +36,6 @@ struct channel_path_desc { struct channel_path; -extern void chsc_process_crw(void); - struct css_general_char { u64 : 41; u32 aif : 1; /* bit 41 */ diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 020566571e0..cf9d27c6f44 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -14,6 +14,7 @@ #include #include +#include "../s390mach.h" #include "css.h" #include "cio.h" #include "cio_debug.h" @@ -530,18 +531,29 @@ EXPORT_SYMBOL_GPL(css_schedule_reprobe); /* * Called from the machine check handler for subchannel report words. */ -void css_process_crw(int rsid1, int rsid2) +static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow) { struct subchannel_id mchk_schid; - CIO_CRW_EVENT(2, "source is subchannel %04X, subsystem id %x\n", - rsid1, rsid2); + if (overflow) { + css_schedule_eval_all(); + return; + } + CIO_CRW_EVENT(2, "CRW0 reports slct=%d, oflw=%d, " + "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", + crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, + crw0->erc, crw0->rsid); + if (crw1) + CIO_CRW_EVENT(2, "CRW1 reports slct=%d, oflw=%d, " + "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", + crw1->slct, crw1->oflw, crw1->chn, crw1->rsc, + crw1->anc, crw1->erc, crw1->rsid); init_subchannel_id(&mchk_schid); - mchk_schid.sch_no = rsid1; - if (rsid2 != 0) - mchk_schid.ssid = (rsid2 >> 8) & 3; + mchk_schid.sch_no = crw0->rsid; + if (crw1) + mchk_schid.ssid = (crw1->rsid >> 8) & 3; - /* + /* * Since we are always presented with IPI in the CRW, we have to * use stsch() to find out if the subchannel in question has come * or gone. @@ -740,6 +752,10 @@ init_channel_subsystem (void) if (ret) goto out; + ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw); + if (ret) + goto out; + if ((ret = bus_register(&css_bus_type))) goto out; @@ -817,6 +833,7 @@ out_unregister: out_bus: bus_unregister(&css_bus_type); out: + s390_unregister_crw_handler(CRW_RSC_CSS); chsc_free_sei_area(); kfree(slow_subchannel_set); printk(KERN_WARNING"cio: failed to initialize css driver (%d)!\n", diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 4cdc132c86b..3ec3dc5a1e5 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -103,7 +103,6 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), int (*fn_unknown)(struct subchannel_id, void *), void *data); extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); -extern void css_process_crw(int, int); extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 5bfbe765983..fe75152a508 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -2,10 +2,10 @@ * drivers/s390/s390mach.c * S/390 machine check handler * - * S390 version - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright IBM Corp. 2000,2008 * Author(s): Ingo Adlung (adlung@de.ibm.com) * Martin Schwidefsky (schwidefsky@de.ibm.com) + * Cornelia Huck */ #include @@ -18,10 +18,6 @@ #include #include #include -#include "cio/cio.h" -#include "cio/chsc.h" -#include "cio/css.h" -#include "cio/chp.h" #include "s390mach.h" static struct semaphore m_sem; @@ -36,13 +32,40 @@ s390_handle_damage(char *msg) for(;;); } +static crw_handler_t crw_handlers[NR_RSCS]; + +/** + * s390_register_crw_handler() - register a channel report word handler + * @rsc: reporting source code to handle + * @handler: handler to be registered + * + * Returns %0 on success and a negative error value otherwise. + */ +int s390_register_crw_handler(int rsc, crw_handler_t handler) +{ + if ((rsc < 0) || (rsc >= NR_RSCS)) + return -EINVAL; + if (!cmpxchg(&crw_handlers[rsc], NULL, handler)) + return 0; + return -EBUSY; +} + +/** + * s390_unregister_crw_handler() - unregister a channel report word handler + * @rsc: reporting source code to handle + */ +void s390_unregister_crw_handler(int rsc) +{ + if ((rsc < 0) || (rsc >= NR_RSCS)) + return; + xchg(&crw_handlers[rsc], NULL); + synchronize_sched(); +} + /* * Retrieve CRWs and call function to handle event. - * - * Note : we currently process CRWs for io and chsc subchannels only */ -static int -s390_collect_crw_info(void *param) +static int s390_collect_crw_info(void *param) { struct crw crw[2]; int ccode; @@ -84,57 +107,24 @@ repeat: crw[chain].rsid); /* Check for overflows. */ if (crw[chain].oflw) { + int i; + pr_debug("%s: crw overflow detected!\n", __func__); - css_schedule_eval_all(); + for (i = 0; i < NR_RSCS; i++) { + if (crw_handlers[i]) + crw_handlers[i](NULL, NULL, 1); + } chain = 0; continue; } - switch (crw[chain].rsc) { - case CRW_RSC_SCH: - if (crw[0].chn && !chain) - break; - pr_debug("source is subchannel %04X\n", crw[0].rsid); - css_process_crw(crw[0].rsid, chain ? crw[1].rsid : 0); - break; - case CRW_RSC_MONITOR: - pr_debug("source is monitoring facility\n"); - break; - case CRW_RSC_CPATH: - pr_debug("source is channel path %02X\n", crw[0].rsid); - /* - * Check for solicited machine checks. These are - * created by reset channel path and need not be - * reported to the common I/O layer. - */ - if (crw[chain].slct) { - pr_debug("solicited machine check for " - "channel path %02X\n", crw[0].rsid); - break; - } - switch (crw[0].erc) { - case CRW_ERC_IPARM: /* Path has come. */ - chp_process_crw(crw[0].rsid, 1); - break; - case CRW_ERC_PERRI: /* Path has gone. */ - case CRW_ERC_PERRN: - chp_process_crw(crw[0].rsid, 0); - break; - default: - pr_debug("Don't know how to handle erc=%x\n", - crw[0].erc); - } - break; - case CRW_RSC_CONFIG: - pr_debug("source is configuration-alert facility\n"); - break; - case CRW_RSC_CSS: - pr_debug("source is channel subsystem\n"); - chsc_process_crw(); - break; - default: - pr_debug("unknown source\n"); - break; + if (crw[0].chn && !chain) { + chain++; + continue; } + if (crw_handlers[crw[chain].rsc]) + crw_handlers[crw[chain].rsc](&crw[0], + chain ? &crw[1] : NULL, + 0); /* chain is always 0 or 1 here. */ chain = crw[chain].chn ? chain + 1 : 0; } diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h index ca681f9b67f..f11e574076d 100644 --- a/drivers/s390/s390mach.h +++ b/drivers/s390/s390mach.h @@ -72,6 +72,13 @@ struct crw { __u32 rsid : 16; /* reporting-source ID */ } __attribute__ ((packed)); +typedef void (*crw_handler_t)(struct crw *, struct crw *, int); + +extern int s390_register_crw_handler(int rsc, crw_handler_t handler); +extern void s390_unregister_crw_handler(int rsc); + +#define NR_RSCS 16 + #define CRW_RSC_MONITOR 0x2 /* monitoring facility */ #define CRW_RSC_SCH 0x3 /* subchannel */ #define CRW_RSC_CPATH 0x4 /* channel path */ -- GitLab From 44a1c19e3b47a7ac596808177ccd250b95f5e688 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:47 +0200 Subject: [PATCH 1754/2509] [S390] cio: Export some symbols for modular css drivers. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 1 + drivers/s390/cio/cio.c | 16 ++++++++++------ drivers/s390/cio/css.c | 5 +++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 672d9731c52..0b3c3109f22 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -95,6 +95,7 @@ u8 chp_get_sch_opm(struct subchannel *sch) } return opm; } +EXPORT_SYMBOL_GPL(chp_get_sch_opm); /** * chp_is_registered - check if a channel-path is registered diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index fdb164f3610..be53f0ee2b1 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -387,8 +387,10 @@ cio_modify (struct subchannel *sch) return ret; } -/* - * Enable subchannel. +/** + * cio_enable_subchannel - enable a subchannel. + * @sch: subchannel to be enabled + * @intparm: interruption parameter to set */ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) { @@ -434,12 +436,13 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) CIO_TRACE_EVENT (2, dbf_txt); return ret; } +EXPORT_SYMBOL_GPL(cio_enable_subchannel); -/* - * Disable subchannel. +/** + * cio_disable_subchannel - disable a subchannel. + * @sch: subchannel to disable */ -int -cio_disable_subchannel (struct subchannel *sch) +int cio_disable_subchannel(struct subchannel *sch) { char dbf_txt[15]; int ccode; @@ -484,6 +487,7 @@ cio_disable_subchannel (struct subchannel *sch) CIO_TRACE_EVENT (2, dbf_txt); return ret; } +EXPORT_SYMBOL_GPL(cio_disable_subchannel); int cio_create_sch_lock(struct subchannel *sch) { diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index cf9d27c6f44..bc3a8e4a49f 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -158,12 +158,17 @@ static int css_sch_device_register(struct subchannel *sch) return ret; } +/** + * css_sch_device_unregister - unregister a subchannel + * @sch: subchannel to be unregistered + */ void css_sch_device_unregister(struct subchannel *sch) { mutex_lock(&sch->reg_mutex); device_unregister(&sch->dev); mutex_unlock(&sch->reg_mutex); } +EXPORT_SYMBOL_GPL(css_sch_device_unregister); static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) { -- GitLab From b3a686f47a3615fcfec0a01c4103c50bb9621369 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:48 +0200 Subject: [PATCH 1755/2509] [S390] cio: Base message subchannel handling. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/cio.c | 30 ++++++++++++++++++++++++------ drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/css.c | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index be53f0ee2b1..0511fe31d04 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -498,13 +498,8 @@ int cio_create_sch_lock(struct subchannel *sch) return 0; } -static int cio_validate_io_subchannel(struct subchannel *sch) +static int cio_check_devno_blacklisted(struct subchannel *sch) { - /* Initialization for io subchannels. */ - if (!css_sch_is_valid(&sch->schib)) - return -ENODEV; - - /* Devno is valid. */ if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { /* * This device must not be known to Linux. So we simply @@ -518,6 +513,26 @@ static int cio_validate_io_subchannel(struct subchannel *sch) return 0; } +static int cio_validate_io_subchannel(struct subchannel *sch) +{ + /* Initialization for io subchannels. */ + if (!css_sch_is_valid(&sch->schib)) + return -ENODEV; + + /* Devno is valid. */ + return cio_check_devno_blacklisted(sch); +} + +static int cio_validate_msg_subchannel(struct subchannel *sch) +{ + /* Initialization for message subchannels. */ + if (!css_sch_is_valid(&sch->schib)) + return -ENODEV; + + /* Devno is valid. */ + return cio_check_devno_blacklisted(sch); +} + /** * cio_validate_subchannel - basic validation of subchannel * @sch: subchannel structure to be filled out @@ -573,6 +588,9 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) case SUBCHANNEL_TYPE_IO: err = cio_validate_io_subchannel(sch); break; + case SUBCHANNEL_TYPE_MSG: + err = cio_validate_msg_subchannel(sch); + break; default: err = 0; } diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 4062748e834..efdb9fd4a84 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -14,7 +14,7 @@ struct pmcw { u32 intparm; /* interruption parameter */ u32 qf : 1; /* qdio facility */ - u32 res0 : 1; /* reserved zeros */ + u32 w : 1; u32 isc : 3; /* interruption sublass */ u32 res5 : 3; /* reserved zeros */ u32 ena : 1; /* enabled */ diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index bc3a8e4a49f..062716cf0f0 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -332,6 +332,8 @@ int css_sch_is_valid(struct schib *schib) { if ((schib->pmcw.st == SUBCHANNEL_TYPE_IO) && !schib->pmcw.dnv) return 0; + if ((schib->pmcw.st == SUBCHANNEL_TYPE_MSG) && !schib->pmcw.w) + return 0; return 1; } EXPORT_SYMBOL_GPL(css_sch_is_valid); -- GitLab From 4f2bd92e3b4f3b6405c5aadae3ad64acd94cdb78 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:58:49 +0200 Subject: [PATCH 1756/2509] [S390] cio: introduce fcx bit to chsc characteristics Introduce fcx bit to chsc characteristics. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chsc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 3b7c044d845..d4498d4005d 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -49,7 +49,9 @@ struct css_general_char { u32 qebsm : 1; /* bit 58 */ u32 : 8; u32 aif_osa : 1; /* bit 67 */ - u32 : 28; + u32 : 20; + u32 fcx : 1; /* bit 88 */ + u32 : 7; }__attribute__((packed)); struct css_chsc_char { -- GitLab From 23d805b647db6c2063a13089497615efa9deacdd Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:58:50 +0200 Subject: [PATCH 1757/2509] [S390] cio: introduce fcx enabled scsw format Extend the scsw data structure to the format required by fcx. Also provide helper functions for easier access to fields which are present in both the traditional as well as the modified format. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/block/dasd.c | 18 +- drivers/s390/block/dasd_3990_erp.c | 15 +- drivers/s390/block/dasd_eckd.c | 12 +- drivers/s390/block/dasd_fba.c | 12 +- drivers/s390/char/con3215.c | 6 +- drivers/s390/char/con3270.c | 6 +- drivers/s390/char/fs3270.c | 6 +- drivers/s390/char/raw3270.c | 16 +- drivers/s390/char/tape_34xx.c | 12 +- drivers/s390/char/tape_3590.c | 21 +- drivers/s390/char/tape_core.c | 15 +- drivers/s390/char/tty3270.c | 6 +- drivers/s390/char/vmur.c | 5 +- drivers/s390/cio/Makefile | 2 +- drivers/s390/cio/cio.c | 14 +- drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/cmf.c | 8 +- drivers/s390/cio/device.c | 2 +- drivers/s390/cio/device_fsm.c | 49 +- drivers/s390/cio/device_id.c | 14 +- drivers/s390/cio/device_ops.c | 17 +- drivers/s390/cio/device_pgid.c | 24 +- drivers/s390/cio/device_status.c | 133 +++-- drivers/s390/cio/qdio.c | 4 +- drivers/s390/cio/scsw.c | 843 +++++++++++++++++++++++++++++ drivers/s390/net/claw.c | 77 +-- drivers/s390/net/ctcm_fsms.c | 12 +- drivers/s390/net/ctcm_main.c | 28 +- drivers/s390/net/lcs.c | 37 +- drivers/s390/net/qeth_core_main.c | 12 +- include/asm-s390/cio.h | 114 +++- 31 files changed, 1254 insertions(+), 288 deletions(-) create mode 100644 drivers/s390/cio/scsw.c diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1a402568336..1b6c52ef733 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -995,14 +995,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, now = get_clock(); DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x", - cdev->dev.bus_id, ((irb->scsw.cstat<<8)|irb->scsw.dstat), - (unsigned int) intparm); + cdev->dev.bus_id, ((irb->scsw.cmd.cstat << 8) | + irb->scsw.cmd.dstat), (unsigned int) intparm); /* check for unsolicited interrupts */ cqr = (struct dasd_ccw_req *) intparm; - if (!cqr || ((irb->scsw.cc == 1) && - (irb->scsw.fctl & SCSW_FCTL_START_FUNC) && - (irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) ) { + if (!cqr || ((irb->scsw.cmd.cc == 1) && + (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) && + (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) { if (cqr && cqr->status == DASD_CQR_IN_IO) cqr->status = DASD_CQR_QUEUED; device = dasd_device_from_cdev_locked(cdev); @@ -1025,7 +1025,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, /* Check for clear pending */ if (cqr->status == DASD_CQR_CLEAR_PENDING && - irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { + irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { cqr->status = DASD_CQR_CLEARED; dasd_device_clear_timer(device); wake_up(&dasd_flush_wq); @@ -1041,11 +1041,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p", - ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); + ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr); next = NULL; expires = 0; - if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && - irb->scsw.cstat == 0 && !irb->esw.esw0.erw.cons) { + if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && + irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) { /* request was completed successfully */ cqr->status = DASD_CQR_SUCCESS; cqr->stopclk = now; diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index e6700df52df..5c6e6f331cb 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -1572,7 +1572,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) /* determine the address of the CCW to be restarted */ /* Imprecise ending is not set -> addr from IRB-SCSW */ - cpa = default_erp->refers->irb.scsw.cpa; + cpa = default_erp->refers->irb.scsw.cmd.cpa; if (cpa == 0) { @@ -1725,7 +1725,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) /* determine the address of the CCW to be restarted */ /* Imprecise ending is not set -> addr from IRB-SCSW */ - cpa = previous_erp->irb.scsw.cpa; + cpa = previous_erp->irb.scsw.cmd.cpa; if (cpa == 0) { @@ -2171,7 +2171,7 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp) { struct dasd_device *device = erp->startdev; - if (erp->refers->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK + if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_CTRL_CHK)) { DEV_MESSAGE(KERN_DEBUG, device, "%s", "channel or interface control check"); @@ -2352,9 +2352,9 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) if ((cqr1->irb.esw.esw0.erw.cons == 0) && (cqr2->irb.esw.esw0.erw.cons == 0)) { - if ((cqr1->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK | + if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_CTRL_CHK)) == - (cqr2->irb.scsw.cstat & (SCHN_STAT_INTF_CTRL_CHK | + (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_CTRL_CHK))) return 1; /* match with ifcc*/ } @@ -2622,8 +2622,9 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) } /* double-check if current erp/cqr was successfull */ - if ((cqr->irb.scsw.cstat == 0x00) && - (cqr->irb.scsw.dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END))) { + if ((cqr->irb.scsw.cmd.cstat == 0x00) && + (cqr->irb.scsw.cmd.dstat == + (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) { DEV_MESSAGE(KERN_DEBUG, device, "ERP called for successful request %p" diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index a0edae091b5..e0b77210d37 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1404,13 +1404,14 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, /* first of all check for state change pending interrupt */ mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; - if ((irb->scsw.dstat & mask) == mask) { + if ((irb->scsw.cmd.dstat & mask) == mask) { dasd_generic_handle_state_change(device); return; } /* summary unit check */ - if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && irb->ecw[7] == 0x0D) { + if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && + (irb->ecw[7] == 0x0D)) { dasd_alias_handle_summary_unit_check(device, irb); return; } @@ -2068,11 +2069,11 @@ static void dasd_eckd_dump_sense(struct dasd_device *device, device->cdev->dev.bus_id); len += sprintf(page + len, KERN_ERR PRINTK_HEADER " in req: %p CS: 0x%02X DS: 0x%02X\n", req, - irb->scsw.cstat, irb->scsw.dstat); + irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); len += sprintf(page + len, KERN_ERR PRINTK_HEADER " device %s: Failing CCW: %p\n", device->cdev->dev.bus_id, - (void *) (addr_t) irb->scsw.cpa); + (void *) (addr_t) irb->scsw.cmd.cpa); if (irb->esw.esw0.erw.cons) { for (sl = 0; sl < 4; sl++) { len += sprintf(page + len, KERN_ERR PRINTK_HEADER @@ -2122,7 +2123,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device, /* scsw->cda is either valid or zero */ len = 0; from = ++to; - fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ + fail = (struct ccw1 *)(addr_t) + irb->scsw.cmd.cpa; /* failing CCW */ if (from < fail - 2) { from = fail - 2; /* there is a gap - print header */ len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 116611583df..aee4656127f 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -222,7 +222,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, /* first of all check for state change pending interrupt */ mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; - if ((irb->scsw.dstat & mask) == mask) { + if ((irb->scsw.cmd.dstat & mask) == mask) { dasd_generic_handle_state_change(device); return; } @@ -449,11 +449,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, device->cdev->dev.bus_id); len += sprintf(page + len, KERN_ERR PRINTK_HEADER " in req: %p CS: 0x%02X DS: 0x%02X\n", req, - irb->scsw.cstat, irb->scsw.dstat); + irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); len += sprintf(page + len, KERN_ERR PRINTK_HEADER " device %s: Failing CCW: %p\n", device->cdev->dev.bus_id, - (void *) (addr_t) irb->scsw.cpa); + (void *) (addr_t) irb->scsw.cmd.cpa); if (irb->esw.esw0.erw.cons) { for (sl = 0; sl < 4; sl++) { len += sprintf(page + len, KERN_ERR PRINTK_HEADER @@ -498,11 +498,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, /* print failing CCW area */ len = 0; - if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { - act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; + if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) { + act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2; len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); } - end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); + end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last); while (act <= end) { len += sprintf(page + len, KERN_ERR PRINTK_HEADER " CCW %p: %08X %08X DAT:", diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 3e5653c92f4..310eda82cde 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -385,8 +385,8 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) raw = cdev->dev.driver_data; req = (struct raw3215_req *) intparm; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; if (cstat != 0) { raw->message = KERN_WARNING "Got nonzero channel status in raw3215_irq " @@ -415,7 +415,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) return; /* That shouldn't happen ... */ if (req->type == RAW3215_READ) { /* store residual count, then wait for device end */ - req->residual = irb->scsw.count; + req->residual = irb->scsw.cmd.count; } if (dstat == 0x08) break; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 0b040557db0..3c07974886e 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -411,15 +411,15 @@ static int con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Schedule tasklet to read aid. */ - if (irb->scsw.dstat & DEV_STAT_ATTENTION) + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) con3270_issue_read(cp); if (rq) { - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) rq->rc = -EIO; else /* Normal end. Copy residual count. */ - rq->rescnt = irb->scsw.count; + rq->rescnt = irb->scsw.cmd.count; } return RAW3270_IO_DONE; } diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index ef36f2132aa..f0d67af9640 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -216,17 +216,17 @@ static int fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Set indication and wake waiters for attention. */ - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { fp->attention = 1; wake_up(&fp->wait); } if (rq) { - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) rq->rc = -EIO; else /* Normal end. Copy residual count. */ - rq->rescnt = irb->scsw.count; + rq->rescnt = irb->scsw.cmd.count; } return RAW3270_IO_DONE; } diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 848ef7e8523..efce32e97be 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -372,17 +372,17 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) if (IS_ERR(irb)) rc = RAW3270_IO_RETRY; - else if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { + else if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) { rq->rc = -EIO; rc = RAW3270_IO_DONE; - } else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END | - DEV_STAT_UNIT_EXCEP)) { + } else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END | + DEV_STAT_UNIT_EXCEP)) { /* Handle CE-DE-UE and subsequent UDE */ set_bit(RAW3270_FLAGS_BUSY, &rp->flags); rc = RAW3270_IO_BUSY; } else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) { /* Wait for UDE if busy flag is set. */ - if (irb->scsw.dstat & DEV_STAT_DEV_END) { + if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { clear_bit(RAW3270_FLAGS_BUSY, &rp->flags); /* Got it, now retry. */ rc = RAW3270_IO_RETRY; @@ -497,7 +497,7 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, * Unit-Check Processing: * Expect Command Reject or Intervention Required. */ - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { /* Request finished abnormally. */ if (irb->ecw[0] & SNS0_INTERVENTION_REQ) { set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags); @@ -505,16 +505,16 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, } } if (rq) { - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { if (irb->ecw[0] & SNS0_CMD_REJECT) rq->rc = -EOPNOTSUPP; else rq->rc = -EIO; } else /* Request finished normally. Copy residual count. */ - rq->rescnt = irb->scsw.count; + rq->rescnt = irb->scsw.cmd.count; } - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { set_bit(RAW3270_FLAGS_ATTN, &view->dev->flags); wake_up(&raw3270_wait_queue); } diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 874adf365e4..22ca34361ed 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -196,7 +196,7 @@ tape_34xx_erp_retry(struct tape_request *request) static int tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb) { - if (irb->scsw.dstat == 0x85 /* READY */) { + if (irb->scsw.cmd.dstat == 0x85) { /* READY */ /* A medium was inserted in the drive. */ DBF_EVENT(6, "xuud med\n"); tape_34xx_delete_sbid_from(device, 0); @@ -844,22 +844,22 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request, if (request == NULL) return tape_34xx_unsolicited_irq(device, irb); - if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) && - (irb->scsw.dstat & DEV_STAT_DEV_END) && + if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) && + (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) && (request->op == TO_WRI)) { /* Write at end of volume */ PRINT_INFO("End of volume\n"); /* XXX */ return tape_34xx_erp_failed(request, -ENOSPC); } - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) return tape_34xx_unit_check(device, request, irb); - if (irb->scsw.dstat & DEV_STAT_DEV_END) { + if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { /* * A unit exception occurs on skipping over a tapemark block. */ - if (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) { + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) { if (request->op == TO_BSB || request->op == TO_FSB) request->rescnt++; else diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 42ce7915fc5..839987618ff 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -837,13 +837,13 @@ tape_3590_erp_retry(struct tape_device *device, struct tape_request *request, static int tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb) { - if (irb->scsw.dstat == DEV_STAT_CHN_END) + if (irb->scsw.cmd.dstat == DEV_STAT_CHN_END) /* Probably result of halt ssch */ return TAPE_IO_PENDING; - else if (irb->scsw.dstat == 0x85) + else if (irb->scsw.cmd.dstat == 0x85) /* Device Ready */ DBF_EVENT(3, "unsol.irq! tape ready: %08x\n", device->cdev_id); - else if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + else if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { tape_3590_schedule_work(device, TO_READ_ATTMSG); } else { DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id); @@ -1515,18 +1515,19 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, if (request == NULL) return tape_3590_unsolicited_irq(device, irb); - if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) && - (irb->scsw.dstat & DEV_STAT_DEV_END) && (request->op == TO_WRI)) { + if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) && + (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) && + (request->op == TO_WRI)) { /* Write at end of volume */ DBF_EVENT(2, "End of volume\n"); return tape_3590_erp_failed(device, request, irb, -ENOSPC); } - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) return tape_3590_unit_check(device, request, irb); - if (irb->scsw.dstat & DEV_STAT_DEV_END) { - if (irb->scsw.dstat == DEV_STAT_UNIT_EXCEP) { + if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { + if (irb->scsw.cmd.dstat == DEV_STAT_UNIT_EXCEP) { if (request->op == TO_FSB || request->op == TO_BSB) request->rescnt++; else @@ -1536,12 +1537,12 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, return tape_3590_done(device, request); } - if (irb->scsw.dstat & DEV_STAT_CHN_END) { + if (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) { DBF_EVENT(2, "cannel end\n"); return TAPE_IO_PENDING; } - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { DBF_EVENT(2, "Unit Attention when busy..\n"); return TAPE_IO_PENDING; } diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index c20e3c54834..181a5441af1 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -839,7 +839,7 @@ tape_dump_sense(struct tape_device* device, struct tape_request *request, PRINT_INFO("-------------------------------------------------\n"); PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n", - irb->scsw.dstat, irb->scsw.cstat, irb->scsw.cpa); + irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa); PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id); if (request != NULL) PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]); @@ -867,7 +867,7 @@ tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request, else op = "---"; DBF_EVENT(3, "DSTAT : %02x CSTAT: %02x\n", - irb->scsw.dstat,irb->scsw.cstat); + irb->scsw.cmd.dstat, irb->scsw.cmd.cstat); DBF_EVENT(3, "DEVICE: %08x OP\t: %s\n", device->cdev_id, op); sptr = (unsigned int *) irb->ecw; DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]); @@ -1083,10 +1083,11 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) * error might still apply. So we just schedule the request to be * started later. */ - if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC) && + if (irb->scsw.cmd.cc != 0 && + (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) && (request->status == TAPE_REQUEST_IN_IO)) { DBF_EVENT(3,"(%08x): deferred cc=%i, fctl=%i. restarting\n", - device->cdev_id, irb->scsw.cc, irb->scsw.fctl); + device->cdev_id, irb->scsw.cmd.cc, irb->scsw.cmd.fctl); request->status = TAPE_REQUEST_QUEUED; schedule_delayed_work(&device->tape_dnr, HZ); return; @@ -1094,8 +1095,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* May be an unsolicited irq */ if(request != NULL) - request->rescnt = irb->scsw.count; - else if ((irb->scsw.dstat == 0x85 || irb->scsw.dstat == 0x80) && + request->rescnt = irb->scsw.cmd.count; + else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) && !list_empty(&device->req_queue)) { /* Not Ready to Ready after long busy ? */ struct tape_request *req; @@ -1111,7 +1112,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) return; } } - if (irb->scsw.dstat != 0x0c) { + if (irb->scsw.cmd.dstat != 0x0c) { /* Set the 'ONLINE' flag depending on sense byte 1 */ if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE) device->tape_generic_status |= GMT_ONLINE(~0); diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 5043150019a..e4ba8bdce32 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -663,7 +663,7 @@ static int tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Schedule tasklet to read aid. */ - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { if (!tp->throttle) tty3270_issue_read(tp, 0); else @@ -671,11 +671,11 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) } if (rq) { - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) rq->rc = -EIO; else /* Normal end. Copy residual count. */ - rq->rescnt = irb->scsw.count; + rq->rescnt = irb->scsw.cmd.count; } return RAW3270_IO_DONE; } diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 83ae9a852f0..49cba9effe8 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -277,7 +277,8 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, struct urdev *urd; TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", - intparm, irb->scsw.cstat, irb->scsw.dstat, irb->scsw.count); + intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, + irb->scsw.cmd.count); if (!intparm) { TRACE("ur_int_handler: unsolicited interrupt\n"); @@ -288,7 +289,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); - else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) + else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) urd->io_request_rc = 0; else urd->io_request_rc = -EIO; diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index cfaf77b320f..9c22e27391d 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -2,7 +2,7 @@ # Makefile for the S/390 common i/o drivers # -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 0511fe31d04..40b2884126d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -128,7 +128,7 @@ cio_tpi(void) local_bh_disable(); irq_enter (); spin_lock(sch->lock); - memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw)); + memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); if (sch->driver && sch->driver->irq) sch->driver->irq(sch); spin_unlock(sch->lock); @@ -202,7 +202,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ /* * initialize device status information */ - sch->schib.scsw.actl |= SCSW_ACTL_START_PEND; + sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND; return 0; case 1: /* status pending */ case 2: /* busy */ @@ -237,7 +237,7 @@ cio_resume (struct subchannel *sch) switch (ccode) { case 0: - sch->schib.scsw.actl |= SCSW_ACTL_RESUME_PEND; + sch->schib.scsw.cmd.actl |= SCSW_ACTL_RESUME_PEND; return 0; case 1: return -EBUSY; @@ -277,7 +277,7 @@ cio_halt(struct subchannel *sch) switch (ccode) { case 0: - sch->schib.scsw.actl |= SCSW_ACTL_HALT_PEND; + sch->schib.scsw.cmd.actl |= SCSW_ACTL_HALT_PEND; return 0; case 1: /* status pending */ case 2: /* busy */ @@ -312,7 +312,7 @@ cio_clear(struct subchannel *sch) switch (ccode) { case 0: - sch->schib.scsw.actl |= SCSW_ACTL_CLEAR_PEND; + sch->schib.scsw.cmd.actl |= SCSW_ACTL_CLEAR_PEND; return 0; default: /* device not operational */ return -ENODEV; @@ -458,7 +458,7 @@ int cio_disable_subchannel(struct subchannel *sch) if (ccode == 3) /* Not operational. */ return -ENODEV; - if (sch->schib.scsw.actl != 0) + if (scsw_actl(&sch->schib.scsw) != 0) /* * the disable function must not be called while there are * requests pending for completion ! @@ -708,7 +708,7 @@ void wait_cons_dev(void) if (!cio_tpi()) cpu_relax(); spin_lock(console_subchannel.lock); - } while (console_subchannel.schib.scsw.actl != 0); + } while (console_subchannel.schib.scsw.cmd.actl != 0); /* * restore previous isc value */ diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index efdb9fd4a84..f7a0cb9fac9 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -48,7 +48,7 @@ struct pmcw { */ struct schib { struct pmcw pmcw; /* path management control word */ - struct scsw scsw; /* subchannel status word */ + union scsw scsw; /* subchannel status word */ __u64 mba; /* measurement block address */ __u8 mda[4]; /* model dependent area */ } __attribute__ ((packed,aligned(4))); diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 2808b6833b9..6c77c2326bd 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -341,12 +341,12 @@ static int cmf_copy_block(struct ccw_device *cdev) if (stsch(sch->schid, &sch->schib)) return -ENODEV; - if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) { + if (scsw_fctl(&sch->schib.scsw) & SCSW_FCTL_START_FUNC) { /* Don't copy if a start function is in progress. */ - if ((!(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED)) && - (sch->schib.scsw.actl & + if ((!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_SUSPENDED)) && + (scsw_actl(&sch->schib.scsw) & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) && - (!(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS))) + (!(scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_SEC_STATUS))) return -EBUSY; } cmb_data = cdev->private->cmb; diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 9281b25087a..215d27dba9e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1281,7 +1281,7 @@ static int check_for_io_on_path(struct subchannel *sch, int mask) cc = stsch(sch->schid, &sch->schib); if (cc) return 0; - if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == mask) + if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask) return 1; return 0; } diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index c9b97cbc220..dc9373031af 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -133,15 +133,15 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) /* Not operational -> done. */ return 0; /* Stage 1: cancel io. */ - if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) && - !(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) { + if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) && + !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { ret = cio_cancel(sch); if (ret != -EINVAL) return ret; /* cancel io unsuccessful. From now on it is asynchronous. */ cdev->private->iretry = 3; /* 3 halt retries. */ } - if (!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) { + if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { /* Stage 2: halt io. */ if (cdev->private->iretry) { cdev->private->iretry--; @@ -551,10 +551,11 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) /* Deliver fake irb to device driver, if needed. */ if (cdev->private->flags.fake_irb) { memset(&cdev->private->irb, 0, sizeof(struct irb)); - cdev->private->irb.scsw.cc = 1; - cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC; - cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND; - cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND; + cdev->private->irb.scsw.cmd.cc = 1; + cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC; + cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND; + cdev->private->irb.scsw.cmd.stctl = + SCSW_STCTL_STATUS_PEND; cdev->private->flags.fake_irb = 0; if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, @@ -648,13 +649,10 @@ ccw_device_offline(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) return -ENODEV; - if (cdev->private->state != DEV_STATE_ONLINE) { - if (sch->schib.scsw.actl != 0) - return -EBUSY; - return -EINVAL; - } - if (sch->schib.scsw.actl != 0) + if (scsw_actl(&sch->schib.scsw) != 0) return -EBUSY; + if (cdev->private->state != DEV_STATE_ONLINE) + return -EINVAL; /* Are we doing path grouping? */ if (!cdev->private->options.pgroup) { /* No, set state offline immediately. */ @@ -729,9 +727,9 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) */ stsch(sch->schid, &sch->schib); - if (sch->schib.scsw.actl != 0 || - (sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) || - (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) { + if (scsw_actl(&sch->schib.scsw) != 0 || + (scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) || + (scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) { /* * No final status yet or final status not yet delivered * to the device driver. Can't do path verfication now, @@ -756,10 +754,8 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; /* Check for unsolicited interrupt. */ - if ((irb->scsw.stctl == - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) - && (!irb->scsw.cc)) { - if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && + if (!scsw_is_solicited(&irb->scsw)) { + if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && !irb->esw.esw0.erw.cons) { /* Unit check but no sense data. Need basic sense. */ if (ccw_device_do_sense(cdev, irb) != 0) @@ -822,9 +818,9 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; /* Check for unsolicited interrupt. */ - if (irb->scsw.stctl == - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - if (irb->scsw.cc == 1) + if (scsw_stctl(&irb->scsw) == + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { + if (scsw_cc(&irb->scsw) == 1) /* Basic sense hasn't started. Try again. */ ccw_device_do_sense(cdev, irb); else { @@ -842,7 +838,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) * only deliver the halt/clear interrupt to the device driver as if it * had killed the original request. */ - if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { + if (scsw_fctl(&irb->scsw) & + (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { /* Retry Basic Sense if requested. */ if (cdev->private->flags.intretry) { cdev->private->flags.intretry = 0; @@ -949,9 +946,9 @@ ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event) case DEV_EVENT_INTERRUPT: irb = (struct irb *) __LC_IRB; /* Check for unsolicited interrupt. */ - if ((irb->scsw.stctl == + if ((scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) && - (!irb->scsw.cc)) + (!scsw_cc(&irb->scsw))) /* FIXME: we should restart stlck here, but this * is extremely unlikely ... */ goto out_wakeup; diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index cba7020517e..5214b2b5425 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -196,7 +196,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) irb = &cdev->private->irb; /* Check the error cases. */ - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { + if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { /* Retry Sense ID if requested. */ if (cdev->private->flags.intretry) { cdev->private->flags.intretry = 0; @@ -234,7 +234,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) irb->ecw[6], irb->ecw[7]); return -EAGAIN; } - if (irb->scsw.cc == 3) { + if (irb->scsw.cmd.cc == 3) { u8 lpm; lpm = to_io_private(sch)->orb.lpm; @@ -248,9 +248,9 @@ ccw_device_check_sense_id(struct ccw_device *cdev) } /* Did we get a proper answer ? */ - if (irb->scsw.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF && + if (irb->scsw.cmd.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF && cdev->private->senseid.reserved == 0xFF) { - if (irb->scsw.count < sizeof(struct senseid) - 8) + if (irb->scsw.cmd.count < sizeof(struct senseid) - 8) cdev->private->flags.esid = 1; return 0; /* Success */ } @@ -260,7 +260,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) "subchannel 0.%x.%04x returns status %02X%02X\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, - irb->scsw.dstat, irb->scsw.cstat); + irb->scsw.cmd.dstat, irb->scsw.cmd.cstat); return -EAGAIN; } @@ -277,9 +277,9 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); irb = (struct irb *) __LC_IRB; /* Retry sense id, if needed. */ - if (irb->scsw.stctl == + if (irb->scsw.cmd.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - if ((irb->scsw.cc == 1) || !irb->scsw.actl) { + if ((irb->scsw.cmd.cc == 1) || !irb->scsw.cmd.actl) { ret = __ccw_device_sense_id_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_id_done(cdev, ret); diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index f308ad55a6d..10f72c5c005 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -179,8 +179,8 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, return -EBUSY; } if (cdev->private->state != DEV_STATE_ONLINE || - ((sch->schib.scsw.stctl & SCSW_STCTL_PRIM_STATUS) && - !(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) || + ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) && + !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) || cdev->private->flags.doverify) return -EBUSY; ret = cio_set_options (sch, flags); @@ -379,7 +379,7 @@ int ccw_device_resume(struct ccw_device *cdev) if (cdev->private->state == DEV_STATE_NOT_OPER) return -ENODEV; if (cdev->private->state != DEV_STATE_ONLINE || - !(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED)) + !(sch->schib.scsw.cmd.actl & SCSW_ACTL_SUSPENDED)) return -EINVAL; return cio_resume(sch); } @@ -404,7 +404,7 @@ ccw_device_call_handler(struct ccw_device *cdev) * - fast notification was requested (primary status) * - unsolicited interrupts */ - stctl = cdev->private->irb.scsw.stctl; + stctl = scsw_stctl(&cdev->private->irb.scsw); ending_status = (stctl & SCSW_STCTL_SEC_STATUS) || (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) || (stctl == SCSW_STCTL_STATUS_PEND); @@ -528,14 +528,15 @@ ccw_device_stlck(struct ccw_device *cdev) cio_disable_subchannel(sch); //FIXME: return code? goto out_unlock; } - cdev->private->irb.scsw.actl |= SCSW_ACTL_START_PEND; + cdev->private->irb.scsw.cmd.actl |= SCSW_ACTL_START_PEND; spin_unlock_irqrestore(sch->lock, flags); - wait_event(cdev->private->wait_q, cdev->private->irb.scsw.actl == 0); + wait_event(cdev->private->wait_q, + cdev->private->irb.scsw.cmd.actl == 0); spin_lock_irqsave(sch->lock, flags); cio_disable_subchannel(sch); //FIXME: return code? - if ((cdev->private->irb.scsw.dstat != + if ((cdev->private->irb.scsw.cmd.dstat != (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) || - (cdev->private->irb.scsw.cstat != 0)) + (cdev->private->irb.scsw.cmd.cstat != 0)) ret = -EIO; /* Clear irb. */ memset(&cdev->private->irb, 0, sizeof(struct irb)); diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 5cf7be008e9..22a711bb544 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -28,13 +28,13 @@ * Helper function called from interrupt context to decide whether an * operation should be tried again. */ -static int __ccw_device_should_retry(struct scsw *scsw) +static int __ccw_device_should_retry(union scsw *scsw) { /* CC is only valid if start function bit is set. */ - if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1) + if ((scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && scsw->cmd.cc == 1) return 1; /* No more activity. For sense and set PGID we stubbornly try again. */ - if (!scsw->actl) + if (!scsw->cmd.actl) return 1; return 0; } @@ -125,7 +125,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); irb = &cdev->private->irb; - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { + if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { /* Retry Sense PGID if requested. */ if (cdev->private->flags.intretry) { cdev->private->flags.intretry = 0; @@ -155,7 +155,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) irb->ecw[6], irb->ecw[7]); return -EAGAIN; } - if (irb->scsw.cc == 3) { + if (irb->scsw.cmd.cc == 3) { u8 lpm; lpm = to_io_private(sch)->orb.lpm; @@ -188,7 +188,7 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; - if (irb->scsw.stctl == + if (irb->scsw.cmd.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { if (__ccw_device_should_retry(&irb->scsw)) { ret = __ccw_device_sense_pgid_start(cdev); @@ -331,7 +331,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); irb = &cdev->private->irb; - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { + if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { /* Retry Set PGID if requested. */ if (cdev->private->flags.intretry) { cdev->private->flags.intretry = 0; @@ -355,7 +355,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) irb->ecw[6], irb->ecw[7]); return -EAGAIN; } - if (irb->scsw.cc == 3) { + if (irb->scsw.cmd.cc == 3) { CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, @@ -376,7 +376,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); irb = &cdev->private->irb; - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { + if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { /* Retry NOP if requested. */ if (cdev->private->flags.intretry) { cdev->private->flags.intretry = 0; @@ -384,7 +384,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) } return -ETIME; } - if (irb->scsw.cc == 3) { + if (irb->scsw.cmd.cc == 3) { CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, @@ -438,7 +438,7 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; - if (irb->scsw.stctl == + if (irb->scsw.cmd.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { if (__ccw_device_should_retry(&irb->scsw)) __ccw_device_verify_start(cdev); @@ -544,7 +544,7 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; - if (irb->scsw.stctl == + if (irb->scsw.cmd.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { if (__ccw_device_should_retry(&irb->scsw)) __ccw_device_disband_start(cdev); diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index 4a38993000f..1b03c5423be 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c @@ -29,9 +29,11 @@ static void ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) { - if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK | - SCHN_STAT_CHN_CTRL_CHK | - SCHN_STAT_INTF_CTRL_CHK))) + char dbf_text[15]; + + if (!scsw_is_valid_cstat(&irb->scsw) || + !(scsw_cstat(&irb->scsw) & (SCHN_STAT_CHN_DATA_CHK | + SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK))) return; CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " "received" @@ -39,15 +41,10 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) ": %02X sch_stat : %02X\n", cdev->private->dev_id.devno, cdev->private->schid.ssid, cdev->private->schid.sch_no, - irb->scsw.dstat, irb->scsw.cstat); - - if (irb->scsw.cc != 3) { - char dbf_text[15]; - - sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no); - CIO_TRACE_EVENT(0, dbf_text); - CIO_HEX_EVENT(0, irb, sizeof (struct irb)); - } + scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw)); + sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no); + CIO_TRACE_EVENT(0, dbf_text); + CIO_HEX_EVENT(0, irb, sizeof(struct irb)); } /* @@ -81,12 +78,12 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb) * are condition that have to be met for the extended control * bit to have meaning. Sick. */ - cdev->private->irb.scsw.ectl = 0; - if ((irb->scsw.stctl & SCSW_STCTL_ALERT_STATUS) && - !(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS)) - cdev->private->irb.scsw.ectl = irb->scsw.ectl; + cdev->private->irb.scsw.cmd.ectl = 0; + if ((irb->scsw.cmd.stctl & SCSW_STCTL_ALERT_STATUS) && + !(irb->scsw.cmd.stctl & SCSW_STCTL_INTER_STATUS)) + cdev->private->irb.scsw.cmd.ectl = irb->scsw.cmd.ectl; /* Check if extended control word is valid. */ - if (!cdev->private->irb.scsw.ectl) + if (!cdev->private->irb.scsw.cmd.ectl) return; /* Copy concurrent sense / model dependent information. */ memcpy (&cdev->private->irb.ecw, irb->ecw, sizeof (irb->ecw)); @@ -98,11 +95,12 @@ ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb) static int ccw_device_accumulate_esw_valid(struct irb *irb) { - if (!irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) + if (!irb->scsw.cmd.eswf && + (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND)) return 0; - if (irb->scsw.stctl == - (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) && - !(irb->scsw.actl & SCSW_ACTL_SUSPENDED)) + if (irb->scsw.cmd.stctl == + (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) && + !(irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED)) return 0; return 1; } @@ -125,7 +123,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb) cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum; /* Copy subchannel logout information if esw is of format 0. */ - if (irb->scsw.eswf) { + if (irb->scsw.cmd.eswf) { cdev_sublog = &cdev_irb->esw.esw0.sublog; sublog = &irb->esw.esw0.sublog; /* Copy extended status flags. */ @@ -134,7 +132,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb) * Copy fields that have a meaning for channel data check * channel control check and interface control check. */ - if (irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK | + if (irb->scsw.cmd.cstat & (SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK)) { /* Copy ancillary report bit. */ @@ -155,7 +153,7 @@ ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb) /* Copy i/o-error alert. */ cdev_sublog->ioerr = sublog->ioerr; /* Copy channel path timeout bit. */ - if (irb->scsw.cstat & SCHN_STAT_INTF_CTRL_CHK) + if (irb->scsw.cmd.cstat & SCHN_STAT_INTF_CTRL_CHK) cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt; /* Copy failing storage address validity flag. */ cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf; @@ -200,24 +198,24 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) * If not, the remaining bit have no meaning and we must ignore them. * The esw is not meaningful as well... */ - if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) + if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) return; /* Check for channel checks and interface control checks. */ ccw_device_msg_control_check(cdev, irb); /* Check for path not operational. */ - if (irb->scsw.pno && irb->scsw.fctl != 0 && - (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) || - (irb->scsw.actl & SCSW_ACTL_SUSPENDED))) + if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw)) ccw_device_path_notoper(cdev); - + /* No irb accumulation for transport mode irbs. */ + if (scsw_is_tm(&irb->scsw)) { + memcpy(&cdev->private->irb, irb, sizeof(struct irb)); + return; + } /* * Don't accumulate unsolicited interrupts. */ - if ((irb->scsw.stctl == - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) && - (!irb->scsw.cc)) + if (!scsw_is_solicited(&irb->scsw)) return; cdev_irb = &cdev->private->irb; @@ -227,62 +225,63 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) * status at the subchannel has been cleared and we must not pass * intermediate accumulated status to the device driver. */ - if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) + if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) memset(&cdev->private->irb, 0, sizeof(struct irb)); /* Copy bits which are valid only for the start function. */ - if (irb->scsw.fctl & SCSW_FCTL_START_FUNC) { + if (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) { /* Copy key. */ - cdev_irb->scsw.key = irb->scsw.key; + cdev_irb->scsw.cmd.key = irb->scsw.cmd.key; /* Copy suspend control bit. */ - cdev_irb->scsw.sctl = irb->scsw.sctl; + cdev_irb->scsw.cmd.sctl = irb->scsw.cmd.sctl; /* Accumulate deferred condition code. */ - cdev_irb->scsw.cc |= irb->scsw.cc; + cdev_irb->scsw.cmd.cc |= irb->scsw.cmd.cc; /* Copy ccw format bit. */ - cdev_irb->scsw.fmt = irb->scsw.fmt; + cdev_irb->scsw.cmd.fmt = irb->scsw.cmd.fmt; /* Copy prefetch bit. */ - cdev_irb->scsw.pfch = irb->scsw.pfch; + cdev_irb->scsw.cmd.pfch = irb->scsw.cmd.pfch; /* Copy initial-status-interruption-control. */ - cdev_irb->scsw.isic = irb->scsw.isic; + cdev_irb->scsw.cmd.isic = irb->scsw.cmd.isic; /* Copy address limit checking control. */ - cdev_irb->scsw.alcc = irb->scsw.alcc; + cdev_irb->scsw.cmd.alcc = irb->scsw.cmd.alcc; /* Copy suppress suspend bit. */ - cdev_irb->scsw.ssi = irb->scsw.ssi; + cdev_irb->scsw.cmd.ssi = irb->scsw.cmd.ssi; } /* Take care of the extended control bit and extended control word. */ ccw_device_accumulate_ecw(cdev, irb); /* Accumulate function control. */ - cdev_irb->scsw.fctl |= irb->scsw.fctl; + cdev_irb->scsw.cmd.fctl |= irb->scsw.cmd.fctl; /* Copy activity control. */ - cdev_irb->scsw.actl= irb->scsw.actl; + cdev_irb->scsw.cmd.actl = irb->scsw.cmd.actl; /* Accumulate status control. */ - cdev_irb->scsw.stctl |= irb->scsw.stctl; + cdev_irb->scsw.cmd.stctl |= irb->scsw.cmd.stctl; /* * Copy ccw address if it is valid. This is a bit simplified * but should be close enough for all practical purposes. */ - if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) || - ((irb->scsw.stctl == + if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) || + ((irb->scsw.cmd.stctl == (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) && - (irb->scsw.actl & SCSW_ACTL_DEVACT) && - (irb->scsw.actl & SCSW_ACTL_SCHACT)) || - (irb->scsw.actl & SCSW_ACTL_SUSPENDED)) - cdev_irb->scsw.cpa = irb->scsw.cpa; + (irb->scsw.cmd.actl & SCSW_ACTL_DEVACT) && + (irb->scsw.cmd.actl & SCSW_ACTL_SCHACT)) || + (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED)) + cdev_irb->scsw.cmd.cpa = irb->scsw.cmd.cpa; /* Accumulate device status, but not the device busy flag. */ - cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; + cdev_irb->scsw.cmd.dstat &= ~DEV_STAT_BUSY; /* dstat is not always valid. */ - if (irb->scsw.stctl & + if (irb->scsw.cmd.stctl & (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS)) - cdev_irb->scsw.dstat |= irb->scsw.dstat; + cdev_irb->scsw.cmd.dstat |= irb->scsw.cmd.dstat; /* Accumulate subchannel status. */ - cdev_irb->scsw.cstat |= irb->scsw.cstat; + cdev_irb->scsw.cmd.cstat |= irb->scsw.cmd.cstat; /* Copy residual count if it is valid. */ - if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) && - (irb->scsw.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN)) == 0) - cdev_irb->scsw.count = irb->scsw.count; + if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) && + (irb->scsw.cmd.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN)) + == 0) + cdev_irb->scsw.cmd.count = irb->scsw.cmd.count; /* Take care of bits in the extended status word. */ ccw_device_accumulate_esw(cdev, irb); @@ -299,7 +298,7 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) * sense facility available/supported when enabling the * concurrent sense facility. */ - if ((cdev_irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && + if ((cdev_irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && !(cdev_irb->esw.esw0.erw.cons)) cdev->private->flags.dosense = 1; } @@ -317,7 +316,7 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) sch = to_subchannel(cdev->dev.parent); /* A sense is required, can we do it now ? */ - if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) + if (scsw_actl(&irb->scsw) & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) /* * we received an Unit Check but we have no final * status yet, therefore we must delay the SENSE @@ -355,20 +354,18 @@ ccw_device_accumulate_basic_sense(struct ccw_device *cdev, struct irb *irb) * If not, the remaining bit have no meaning and we must ignore them. * The esw is not meaningful as well... */ - if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) + if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) return; /* Check for channel checks and interface control checks. */ ccw_device_msg_control_check(cdev, irb); /* Check for path not operational. */ - if (irb->scsw.pno && irb->scsw.fctl != 0 && - (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) || - (irb->scsw.actl & SCSW_ACTL_SUSPENDED))) + if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw)) ccw_device_path_notoper(cdev); - if (!(irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && - (irb->scsw.dstat & DEV_STAT_CHN_END)) { + if (!(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && + (irb->scsw.cmd.dstat & DEV_STAT_CHN_END)) { cdev->private->irb.esw.esw0.erw.cons = 1; cdev->private->flags.dosense = 0; } @@ -386,11 +383,11 @@ int ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb) { ccw_device_accumulate_irb(cdev, irb); - if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) + if ((irb->scsw.cmd.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0) return -EBUSY; /* Check for basic sense. */ if (cdev->private->flags.dosense && - !(irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) { + !(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)) { cdev->private->irb.esw.esw0.erw.cons = 1; cdev->private->flags.dosense = 0; return 0; diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 17df222dea8..72508d8f3c4 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -2140,8 +2140,8 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) QDIO_DBF_TEXT4(0, trace, dbf_text); #endif /* CONFIG_QDIO_DEBUG */ - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; switch (irq_ptr->state) { case QDIO_IRQ_STATE_INACTIVE: diff --git a/drivers/s390/cio/scsw.c b/drivers/s390/cio/scsw.c new file mode 100644 index 00000000000..f8da25ab576 --- /dev/null +++ b/drivers/s390/cio/scsw.c @@ -0,0 +1,843 @@ +/* + * Helper functions for scsw access. + * + * Copyright IBM Corp. 2008 + * Author(s): Peter Oberparleiter + */ + +#include +#include +#include +#include "css.h" +#include "chsc.h" + +/** + * scsw_is_tm - check for transport mode scsw + * @scsw: pointer to scsw + * + * Return non-zero if the specified scsw is a transport mode scsw, zero + * otherwise. + */ +int scsw_is_tm(union scsw *scsw) +{ + return css_general_characteristics.fcx && (scsw->tm.x == 1); +} +EXPORT_SYMBOL(scsw_is_tm); + +/** + * scsw_key - return scsw key field + * @scsw: pointer to scsw + * + * Return the value of the key field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_key(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.key; + else + return scsw->cmd.key; +} +EXPORT_SYMBOL(scsw_key); + +/** + * scsw_eswf - return scsw eswf field + * @scsw: pointer to scsw + * + * Return the value of the eswf field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_eswf(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.eswf; + else + return scsw->cmd.eswf; +} +EXPORT_SYMBOL(scsw_eswf); + +/** + * scsw_cc - return scsw cc field + * @scsw: pointer to scsw + * + * Return the value of the cc field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_cc(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.cc; + else + return scsw->cmd.cc; +} +EXPORT_SYMBOL(scsw_cc); + +/** + * scsw_ectl - return scsw ectl field + * @scsw: pointer to scsw + * + * Return the value of the ectl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_ectl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.ectl; + else + return scsw->cmd.ectl; +} +EXPORT_SYMBOL(scsw_ectl); + +/** + * scsw_pno - return scsw pno field + * @scsw: pointer to scsw + * + * Return the value of the pno field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_pno(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.pno; + else + return scsw->cmd.pno; +} +EXPORT_SYMBOL(scsw_pno); + +/** + * scsw_fctl - return scsw fctl field + * @scsw: pointer to scsw + * + * Return the value of the fctl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_fctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.fctl; + else + return scsw->cmd.fctl; +} +EXPORT_SYMBOL(scsw_fctl); + +/** + * scsw_actl - return scsw actl field + * @scsw: pointer to scsw + * + * Return the value of the actl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_actl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.actl; + else + return scsw->cmd.actl; +} +EXPORT_SYMBOL(scsw_actl); + +/** + * scsw_stctl - return scsw stctl field + * @scsw: pointer to scsw + * + * Return the value of the stctl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_stctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.stctl; + else + return scsw->cmd.stctl; +} +EXPORT_SYMBOL(scsw_stctl); + +/** + * scsw_dstat - return scsw dstat field + * @scsw: pointer to scsw + * + * Return the value of the dstat field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_dstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.dstat; + else + return scsw->cmd.dstat; +} +EXPORT_SYMBOL(scsw_dstat); + +/** + * scsw_cstat - return scsw cstat field + * @scsw: pointer to scsw + * + * Return the value of the cstat field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +u32 scsw_cstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.cstat; + else + return scsw->cmd.cstat; +} +EXPORT_SYMBOL(scsw_cstat); + +/** + * scsw_cmd_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_key(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_key); + +/** + * scsw_cmd_is_valid_sctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_sctl(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_sctl); + +/** + * scsw_cmd_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_eswf(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_eswf); + +/** + * scsw_cmd_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_cc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && + (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_cc); + +/** + * scsw_cmd_is_valid_fmt - check fmt field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fmt field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_fmt(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_fmt); + +/** + * scsw_cmd_is_valid_pfch - check pfch field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pfch field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_pfch(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_pfch); + +/** + * scsw_cmd_is_valid_isic - check isic field validity + * @scsw: pointer to scsw + * + * Return non-zero if the isic field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_isic(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_isic); + +/** + * scsw_cmd_is_valid_alcc - check alcc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the alcc field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_alcc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_alcc); + +/** + * scsw_cmd_is_valid_ssi - check ssi field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ssi field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_ssi(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_ssi); + +/** + * scsw_cmd_is_valid_zcc - check zcc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the zcc field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_zcc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && + (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_zcc); + +/** + * scsw_cmd_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_ectl(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_ectl); + +/** + * scsw_cmd_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_pno(union scsw *scsw) +{ + return (scsw->cmd.fctl != 0) && + (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || + ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_pno); + +/** + * scsw_cmd_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_fctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_cmd_is_valid_fctl); + +/** + * scsw_cmd_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_actl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_cmd_is_valid_actl); + +/** + * scsw_cmd_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_stctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_cmd_is_valid_stctl); + +/** + * scsw_cmd_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_dstat(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->cmd.cc != 3); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_dstat); + +/** + * scsw_cmd_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified command mode scsw is + * valid, zero otherwise. + */ +int scsw_cmd_is_valid_cstat(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->cmd.cc != 3); +} +EXPORT_SYMBOL(scsw_cmd_is_valid_cstat); + +/** + * scsw_tm_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_key(union scsw *scsw) +{ + return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); +} +EXPORT_SYMBOL(scsw_tm_is_valid_key); + +/** + * scsw_tm_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_eswf(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); +} +EXPORT_SYMBOL(scsw_tm_is_valid_eswf); + +/** + * scsw_tm_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_cc(union scsw *scsw) +{ + return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && + (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); +} +EXPORT_SYMBOL(scsw_tm_is_valid_cc); + +/** + * scsw_tm_is_valid_fmt - check fmt field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fmt field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_fmt(union scsw *scsw) +{ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_fmt); + +/** + * scsw_tm_is_valid_x - check x field validity + * @scsw: pointer to scsw + * + * Return non-zero if the x field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_x(union scsw *scsw) +{ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_x); + +/** + * scsw_tm_is_valid_q - check q field validity + * @scsw: pointer to scsw + * + * Return non-zero if the q field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_q(union scsw *scsw) +{ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_q); + +/** + * scsw_tm_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_ectl(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); +} +EXPORT_SYMBOL(scsw_tm_is_valid_ectl); + +/** + * scsw_tm_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_pno(union scsw *scsw) +{ + return (scsw->tm.fctl != 0) && + (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || + ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); +} +EXPORT_SYMBOL(scsw_tm_is_valid_pno); + +/** + * scsw_tm_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_fctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_fctl); + +/** + * scsw_tm_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_actl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_actl); + +/** + * scsw_tm_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_stctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_stctl); + +/** + * scsw_tm_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_dstat(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->tm.cc != 3); +} +EXPORT_SYMBOL(scsw_tm_is_valid_dstat); + +/** + * scsw_tm_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_cstat(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->tm.cc != 3); +} +EXPORT_SYMBOL(scsw_tm_is_valid_cstat); + +/** + * scsw_tm_is_valid_fcxs - check fcxs field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fcxs field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_fcxs(union scsw *scsw) +{ + return 1; +} +EXPORT_SYMBOL(scsw_tm_is_valid_fcxs); + +/** + * scsw_tm_is_valid_schxs - check schxs field validity + * @scsw: pointer to scsw + * + * Return non-zero if the schxs field of the specified transport mode scsw is + * valid, zero otherwise. + */ +int scsw_tm_is_valid_schxs(union scsw *scsw) +{ + return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | + SCHN_STAT_INTF_CTRL_CHK | + SCHN_STAT_PROT_CHECK | + SCHN_STAT_CHN_DATA_CHK)); +} +EXPORT_SYMBOL(scsw_tm_is_valid_schxs); + +/** + * scsw_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_actl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_actl(scsw); + else + return scsw_cmd_is_valid_actl(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_actl); + +/** + * scsw_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_cc(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_cc(scsw); + else + return scsw_cmd_is_valid_cc(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_cc); + +/** + * scsw_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_cstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_cstat(scsw); + else + return scsw_cmd_is_valid_cstat(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_cstat); + +/** + * scsw_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_dstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_dstat(scsw); + else + return scsw_cmd_is_valid_dstat(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_dstat); + +/** + * scsw_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_ectl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_ectl(scsw); + else + return scsw_cmd_is_valid_ectl(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_ectl); + +/** + * scsw_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_eswf(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_eswf(scsw); + else + return scsw_cmd_is_valid_eswf(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_eswf); + +/** + * scsw_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_fctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_fctl(scsw); + else + return scsw_cmd_is_valid_fctl(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_fctl); + +/** + * scsw_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_key(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_key(scsw); + else + return scsw_cmd_is_valid_key(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_key); + +/** + * scsw_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_pno(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_pno(scsw); + else + return scsw_cmd_is_valid_pno(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_pno); + +/** + * scsw_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +int scsw_is_valid_stctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_stctl(scsw); + else + return scsw_cmd_is_valid_stctl(scsw); +} +EXPORT_SYMBOL(scsw_is_valid_stctl); + +/** + * scsw_cmd_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the command mode scsw indicates that the associated + * status condition is solicited, zero if it is unsolicited. + */ +int scsw_cmd_is_solicited(union scsw *scsw) +{ + return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); +} +EXPORT_SYMBOL(scsw_cmd_is_solicited); + +/** + * scsw_tm_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the transport mode scsw indicates that the associated + * status condition is solicited, zero if it is unsolicited. + */ +int scsw_tm_is_solicited(union scsw *scsw) +{ + return (scsw->tm.cc != 0) || (scsw->tm.stctl != + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); +} +EXPORT_SYMBOL(scsw_tm_is_solicited); + +/** + * scsw_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the transport or command mode scsw indicates that the + * associated status condition is solicited, zero if it is unsolicited. + */ +int scsw_is_solicited(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_solicited(scsw); + else + return scsw_cmd_is_solicited(scsw); +} +EXPORT_SYMBOL(scsw_is_solicited); diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 04a1d7bf678..c644669a75c 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -703,7 +703,8 @@ claw_irq_handler(struct ccw_device *cdev, if (!cdev->dev.driver_data) { printk(KERN_WARNING "claw: unsolicited interrupt for device:" "%s received c-%02x d-%02x\n", - cdev->dev.bus_id,irb->scsw.cstat, irb->scsw.dstat); + cdev->dev.bus_id, irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); #ifdef FUNCTRACE printk(KERN_INFO "claw: %s() " "exit on line %d\n",__func__,__LINE__); @@ -732,22 +733,23 @@ claw_irq_handler(struct ccw_device *cdev, #ifdef IOTRACE printk(KERN_INFO "%s: interrupt for device: %04x " "received c-%02x d-%02x state-%02x\n", - dev->name, p_ch->devno, irb->scsw.cstat, - irb->scsw.dstat, p_ch->claw_state); + dev->name, p_ch->devno, irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat, p_ch->claw_state); #endif /* Copy interruption response block. */ memcpy(p_ch->irb, irb, sizeof(struct irb)); /* Check for good subchannel return code, otherwise error message */ - if (irb->scsw.cstat && !(irb->scsw.cstat & SCHN_STAT_PCI)) { + if (irb->scsw.cmd.cstat && !(irb->scsw.cmd.cstat & SCHN_STAT_PCI)) { printk(KERN_INFO "%s: subchannel check for device: %04x -" " Sch Stat %02x Dev Stat %02x CPA - %04x\n", dev->name, p_ch->devno, - irb->scsw.cstat, irb->scsw.dstat,irb->scsw.cpa); + irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, + irb->scsw.cmd.cpa); #ifdef IOTRACE dumpit((char *)irb,sizeof(struct irb)); - dumpit((char *)(unsigned long)irb->scsw.cpa, + dumpit((char *)(unsigned long)irb->scsw.cmd.cpa, sizeof(struct ccw1)); #endif #ifdef FUNCTRACE @@ -759,22 +761,24 @@ claw_irq_handler(struct ccw_device *cdev, } /* Check the reason-code of a unit check */ - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) ccw_check_unit_check(p_ch, irb->ecw[0]); - } /* State machine to bring the connection up, down and to restart */ - p_ch->last_dstat = irb->scsw.dstat; + p_ch->last_dstat = irb->scsw.cmd.dstat; switch (p_ch->claw_state) { case CLAW_STOP:/* HALT_IO by claw_release (halt sequence) */ #ifdef DEBUGMSG printk(KERN_INFO "%s: CLAW_STOP enter\n", dev->name); #endif - if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || - (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || - (p_ch->irb->scsw.stctl == - (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { + if (!((p_ch->irb->scsw.cmd.stctl & + SCSW_STCTL_SEC_STATUS) || + (p_ch->irb->scsw.cmd.stctl == + SCSW_STCTL_STATUS_PEND) || + (p_ch->irb->scsw.cmd.stctl == + (SCSW_STCTL_ALERT_STATUS | + SCSW_STCTL_STATUS_PEND)))) { #ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__func__,__LINE__); @@ -798,10 +802,13 @@ claw_irq_handler(struct ccw_device *cdev, printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO\n", dev->name); #endif - if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || - (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || - (p_ch->irb->scsw.stctl == - (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { + if (!((p_ch->irb->scsw.cmd.stctl & + SCSW_STCTL_SEC_STATUS) || + (p_ch->irb->scsw.cmd.stctl == + SCSW_STCTL_STATUS_PEND) || + (p_ch->irb->scsw.cmd.stctl == + (SCSW_STCTL_ALERT_STATUS | + SCSW_STCTL_STATUS_PEND)))) { #ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__func__,__LINE__); @@ -828,8 +835,8 @@ claw_irq_handler(struct ccw_device *cdev, "interrupt for device:" "%s received c-%02x d-%02x\n", cdev->dev.bus_id, - irb->scsw.cstat, - irb->scsw.dstat); + irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); return; } #ifdef DEBUGMSG @@ -844,7 +851,7 @@ claw_irq_handler(struct ccw_device *cdev, return; case CLAW_START_READ: CLAW_DBF_TEXT(4,trace,"ReadIRQ"); - if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { clear_bit(0, (void *)&p_ch->IO_active); if ((p_ch->irb->ecw[0] & 0x41) == 0x41 || (p_ch->irb->ecw[0] & 0x40) == 0x40 || @@ -863,8 +870,8 @@ claw_irq_handler(struct ccw_device *cdev, CLAW_DBF_TEXT(4,trace,"notrdy"); return; } - if ((p_ch->irb->scsw.cstat & SCHN_STAT_PCI) && - (p_ch->irb->scsw.dstat==0)) { + if ((p_ch->irb->scsw.cmd.cstat & SCHN_STAT_PCI) && + (p_ch->irb->scsw.cmd.dstat == 0)) { if (test_and_set_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a) == 0) { tasklet_schedule(&p_ch->tasklet); @@ -879,10 +886,13 @@ claw_irq_handler(struct ccw_device *cdev, CLAW_DBF_TEXT(4,trace,"PCI_read"); return; } - if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || - (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || - (p_ch->irb->scsw.stctl == - (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { + if (!((p_ch->irb->scsw.cmd.stctl & + SCSW_STCTL_SEC_STATUS) || + (p_ch->irb->scsw.cmd.stctl == + SCSW_STCTL_STATUS_PEND) || + (p_ch->irb->scsw.cmd.stctl == + (SCSW_STCTL_ALERT_STATUS | + SCSW_STCTL_STATUS_PEND)))) { #ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__func__,__LINE__); @@ -911,7 +921,7 @@ claw_irq_handler(struct ccw_device *cdev, CLAW_DBF_TEXT(4,trace,"RdIRQXit"); return; case CLAW_START_WRITE: - if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { printk(KERN_INFO "%s: Unit Check Occured in " "write channel\n",dev->name); clear_bit(0, (void *)&p_ch->IO_active); @@ -934,16 +944,19 @@ claw_irq_handler(struct ccw_device *cdev, CLAW_DBF_TEXT(4,trace,"rstrtwrt"); return; } - if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) { + if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) { clear_bit(0, (void *)&p_ch->IO_active); printk(KERN_INFO "%s: Unit Exception " "Occured in write channel\n", dev->name); } - if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || - (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || - (p_ch->irb->scsw.stctl == - (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { + if (!((p_ch->irb->scsw.cmd.stctl & + SCSW_STCTL_SEC_STATUS) || + (p_ch->irb->scsw.cmd.stctl == + SCSW_STCTL_STATUS_PEND) || + (p_ch->irb->scsw.cmd.stctl == + (SCSW_STCTL_ALERT_STATUS | + SCSW_STCTL_STATUS_PEND)))) { #ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__func__,__LINE__); diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 2a106f3a076..7e6bd387f4d 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -257,9 +257,9 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg) if (duration > ch->prof.tx_time) ch->prof.tx_time = duration; - if (ch->irb->scsw.count != 0) + if (ch->irb->scsw.cmd.count != 0) ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n", - dev->name, ch->irb->scsw.count); + dev->name, ch->irb->scsw.cmd.count); fsm_deltimer(&ch->timer); while ((skb = skb_dequeue(&ch->io_queue))) { priv->stats.tx_packets++; @@ -353,7 +353,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg) struct channel *ch = arg; struct net_device *dev = ch->netdev; struct ctcm_priv *priv = dev->priv; - int len = ch->max_bufsize - ch->irb->scsw.count; + int len = ch->max_bufsize - ch->irb->scsw.cmd.count; struct sk_buff *skb = ch->trans_skb; __u16 block_len = *((__u16 *)skb->data); int check_len; @@ -1234,9 +1234,9 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) if (duration > ch->prof.tx_time) ch->prof.tx_time = duration; - if (ch->irb->scsw.count != 0) + if (ch->irb->scsw.cmd.count != 0) ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n", - dev->name, ch->irb->scsw.count); + dev->name, ch->irb->scsw.cmd.count); fsm_deltimer(&ch->timer); while ((skb = skb_dequeue(&ch->io_queue))) { priv->stats.tx_packets++; @@ -1394,7 +1394,7 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg) struct sk_buff *skb = ch->trans_skb; struct sk_buff *new_skb; unsigned long saveflags = 0; /* avoids compiler warning */ - int len = ch->max_bufsize - ch->irb->scsw.count; + int len = ch->max_bufsize - ch->irb->scsw.cmd.count; if (do_debug_data) { CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx %s cp:%i %s\n", diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index d52843da4f5..6b13c1c1beb 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1236,8 +1236,8 @@ static void ctcm_irq_handler(struct ccw_device *cdev, /* Check for unsolicited interrupts. */ if (cgdev == NULL) { ctcm_pr_warn("ctcm: Got unsolicited irq: %s c-%02x d-%02x\n", - cdev->dev.bus_id, irb->scsw.cstat, - irb->scsw.dstat); + cdev->dev.bus_id, irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); return; } @@ -1266,40 +1266,40 @@ static void ctcm_irq_handler(struct ccw_device *cdev, "received c-%02x d-%02x\n", dev->name, ch->id, - irb->scsw.cstat, - irb->scsw.dstat); + irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); /* Copy interruption response block. */ memcpy(ch->irb, irb, sizeof(struct irb)); /* Check for good subchannel return code, otherwise error message */ - if (irb->scsw.cstat) { + if (irb->scsw.cmd.cstat) { fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch); ctcm_pr_warn("%s: subchannel check for dev: %s - %02x %02x\n", - dev->name, ch->id, irb->scsw.cstat, - irb->scsw.dstat); + dev->name, ch->id, irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); return; } /* Check the reason-code of a unit check */ - if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { ccw_unit_check(ch, irb->ecw[0]); return; } - if (irb->scsw.dstat & DEV_STAT_BUSY) { - if (irb->scsw.dstat & DEV_STAT_ATTENTION) + if (irb->scsw.cmd.dstat & DEV_STAT_BUSY) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) fsm_event(ch->fsm, CTC_EVENT_ATTNBUSY, ch); else fsm_event(ch->fsm, CTC_EVENT_BUSY, ch); return; } - if (irb->scsw.dstat & DEV_STAT_ATTENTION) { + if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) { fsm_event(ch->fsm, CTC_EVENT_ATTN, ch); return; } - if ((irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || - (irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || - (irb->scsw.stctl == + if ((irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) || + (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) || + (irb->scsw.cmd.stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))) fsm_event(ch->fsm, CTC_EVENT_FINSTAT, ch); else diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index dd22f4b3703..586cca21da9 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1327,8 +1327,8 @@ lcs_get_problem(struct ccw_device *cdev, struct irb *irb) char *sense; sense = (char *) irb->ecw; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | @@ -1388,11 +1388,13 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else channel = &card->write; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id); - LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat); - LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl); + LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.cstat, + irb->scsw.cmd.dstat); + LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.fctl, + irb->scsw.cmd.actl); /* Check for channel and device errors presented */ rc = lcs_get_problem(cdev, irb); @@ -1410,11 +1412,11 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } /* How far in the ccw chain have we processed? */ if ((channel->state != LCS_CH_STATE_INIT) && - (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { - index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) + (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC)) { + index = (struct ccw1 *) __va((addr_t) irb->scsw.cmd.cpa) - channel->ccws; - if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) || - (irb->scsw.cstat & SCHN_STAT_PCI)) + if ((irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED) || + (irb->scsw.cmd.cstat & SCHN_STAT_PCI)) /* Bloody io subsystem tells us lies about cpa... */ index = (index - 1) & (LCS_NUM_BUFFS - 1); while (channel->io_idx != index) { @@ -1425,25 +1427,24 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } } - if ((irb->scsw.dstat & DEV_STAT_DEV_END) || - (irb->scsw.dstat & DEV_STAT_CHN_END) || - (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) + if ((irb->scsw.cmd.dstat & DEV_STAT_DEV_END) || + (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) || + (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)) /* Mark channel as stopped. */ channel->state = LCS_CH_STATE_STOPPED; - else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED) + else if (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED) /* CCW execution stopped on a suspend bit. */ channel->state = LCS_CH_STATE_SUSPENDED; - if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { - if (irb->scsw.cc != 0) { + if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) { + if (irb->scsw.cmd.cc != 0) { ccw_device_halt(channel->ccwdev, (addr_t) channel); return; } /* The channel has been stopped by halt_IO. */ channel->state = LCS_CH_STATE_HALTED; } - if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { + if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) channel->state = LCS_CH_STATE_CLEARED; - } /* Do the rest in the tasklet. */ tasklet_schedule(&channel->irq_tasklet); } diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 9a71dae223e..90db3e444f3 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -735,8 +735,8 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb) char *sense; sense = (char *) irb->ecw; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | @@ -823,8 +823,8 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, if (__qeth_check_irb_error(cdev, intparm, irb)) return; - cstat = irb->scsw.cstat; - dstat = irb->scsw.dstat; + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; card = CARD_FROM_CDEV(cdev); if (!card) @@ -842,10 +842,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } atomic_set(&channel->irq_pending, 0); - if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC)) + if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC)) channel->state = CH_STATE_STOPPED; - if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC)) + if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC)) channel->state = CH_STATE_HALTED; /*let's wake up immediately on data channel*/ diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index 0818ecd30ca..6dccb071aec 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h @@ -16,7 +16,7 @@ #define __MAX_CSSID 0 /** - * struct scsw - subchannel status word + * struct cmd_scsw - command-mode subchannel status word * @key: subchannel key * @sctl: suspend control * @eswf: esw format @@ -38,7 +38,7 @@ * @cstat: subchannel status * @count: residual count */ -struct scsw { +struct cmd_scsw { __u32 key : 4; __u32 sctl : 1; __u32 eswf : 1; @@ -61,6 +61,114 @@ struct scsw { __u32 count : 16; } __attribute__ ((packed)); +/** + * struct tm_scsw - transport-mode subchannel status word + * @key: subchannel key + * @eswf: esw format + * @cc: deferred condition code + * @fmt: format + * @x: IRB-format control + * @q: interrogate-complete + * @ectl: extended control + * @pno: path not operational + * @fctl: function control + * @actl: activity control + * @stctl: status control + * @tcw: TCW address + * @dstat: device status + * @cstat: subchannel status + * @fcxs: FCX status + * @schxs: subchannel-extended status + */ +struct tm_scsw { + u32 key:4; + u32 :1; + u32 eswf:1; + u32 cc:2; + u32 fmt:3; + u32 x:1; + u32 q:1; + u32 :1; + u32 ectl:1; + u32 pno:1; + u32 :1; + u32 fctl:3; + u32 actl:7; + u32 stctl:5; + u32 tcw; + u32 dstat:8; + u32 cstat:8; + u32 fcxs:8; + u32 schxs:8; +} __attribute__ ((packed)); + +/** + * union scsw - subchannel status word + * @cmd: command-mode SCSW + * @tm: transport-mode SCSW + */ +union scsw { + struct cmd_scsw cmd; + struct tm_scsw tm; +} __attribute__ ((packed)); + +int scsw_is_tm(union scsw *scsw); +u32 scsw_key(union scsw *scsw); +u32 scsw_eswf(union scsw *scsw); +u32 scsw_cc(union scsw *scsw); +u32 scsw_ectl(union scsw *scsw); +u32 scsw_pno(union scsw *scsw); +u32 scsw_fctl(union scsw *scsw); +u32 scsw_actl(union scsw *scsw); +u32 scsw_stctl(union scsw *scsw); +u32 scsw_dstat(union scsw *scsw); +u32 scsw_cstat(union scsw *scsw); +int scsw_is_solicited(union scsw *scsw); +int scsw_is_valid_key(union scsw *scsw); +int scsw_is_valid_eswf(union scsw *scsw); +int scsw_is_valid_cc(union scsw *scsw); +int scsw_is_valid_ectl(union scsw *scsw); +int scsw_is_valid_pno(union scsw *scsw); +int scsw_is_valid_fctl(union scsw *scsw); +int scsw_is_valid_actl(union scsw *scsw); +int scsw_is_valid_stctl(union scsw *scsw); +int scsw_is_valid_dstat(union scsw *scsw); +int scsw_is_valid_cstat(union scsw *scsw); +int scsw_cmd_is_valid_key(union scsw *scsw); +int scsw_cmd_is_valid_sctl(union scsw *scsw); +int scsw_cmd_is_valid_eswf(union scsw *scsw); +int scsw_cmd_is_valid_cc(union scsw *scsw); +int scsw_cmd_is_valid_fmt(union scsw *scsw); +int scsw_cmd_is_valid_pfch(union scsw *scsw); +int scsw_cmd_is_valid_isic(union scsw *scsw); +int scsw_cmd_is_valid_alcc(union scsw *scsw); +int scsw_cmd_is_valid_ssi(union scsw *scsw); +int scsw_cmd_is_valid_zcc(union scsw *scsw); +int scsw_cmd_is_valid_ectl(union scsw *scsw); +int scsw_cmd_is_valid_pno(union scsw *scsw); +int scsw_cmd_is_valid_fctl(union scsw *scsw); +int scsw_cmd_is_valid_actl(union scsw *scsw); +int scsw_cmd_is_valid_stctl(union scsw *scsw); +int scsw_cmd_is_valid_dstat(union scsw *scsw); +int scsw_cmd_is_valid_cstat(union scsw *scsw); +int scsw_cmd_is_solicited(union scsw *scsw); +int scsw_tm_is_valid_key(union scsw *scsw); +int scsw_tm_is_valid_eswf(union scsw *scsw); +int scsw_tm_is_valid_cc(union scsw *scsw); +int scsw_tm_is_valid_fmt(union scsw *scsw); +int scsw_tm_is_valid_x(union scsw *scsw); +int scsw_tm_is_valid_q(union scsw *scsw); +int scsw_tm_is_valid_ectl(union scsw *scsw); +int scsw_tm_is_valid_pno(union scsw *scsw); +int scsw_tm_is_valid_fctl(union scsw *scsw); +int scsw_tm_is_valid_actl(union scsw *scsw); +int scsw_tm_is_valid_stctl(union scsw *scsw); +int scsw_tm_is_valid_dstat(union scsw *scsw); +int scsw_tm_is_valid_cstat(union scsw *scsw); +int scsw_tm_is_valid_fcxs(union scsw *scsw); +int scsw_tm_is_valid_schxs(union scsw *scsw); +int scsw_tm_is_solicited(union scsw *scsw); + #define SCSW_FCTL_CLEAR_FUNC 0x1 #define SCSW_FCTL_HALT_FUNC 0x2 #define SCSW_FCTL_START_FUNC 0x4 @@ -303,7 +411,7 @@ struct esw3 { * if applicable). */ struct irb { - struct scsw scsw; + union scsw scsw; union { struct esw0 esw0; struct esw1 esw1; -- GitLab From 83262d6349e60b9d10798d489719d80029c00798 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:58:51 +0200 Subject: [PATCH 1758/2509] [S390] cio: provide functions for fcx enabled I/O Provide functions for assembling and starting fcx enabled I/O request blocks. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/Makefile | 2 +- drivers/s390/cio/cio.c | 81 ++++++-- drivers/s390/cio/cio.h | 5 + drivers/s390/cio/device_fsm.c | 49 +++-- drivers/s390/cio/device_id.c | 2 +- drivers/s390/cio/device_ops.c | 117 +++++++++++ drivers/s390/cio/device_pgid.c | 2 +- drivers/s390/cio/fcx.c | 350 +++++++++++++++++++++++++++++++++ drivers/s390/cio/io_sch.h | 46 ++++- include/asm-s390/ccwdev.h | 12 ++ include/asm-s390/fcx.h | 311 +++++++++++++++++++++++++++++ 11 files changed, 939 insertions(+), 38 deletions(-) create mode 100644 drivers/s390/cio/fcx.c create mode 100644 include/asm-s390/fcx.h diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 9c22e27391d..ee3c416243b 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -2,7 +2,7 @@ # Makefile for the S/390 common i/o drivers # -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 40b2884126d..c24dfcd858d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "cio.h" #include "css.h" #include "chsc.h" @@ -167,30 +168,30 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ { char dbf_txt[15]; int ccode; - struct orb *orb; + union orb *orb; CIO_TRACE_EVENT(4, "stIO"); CIO_TRACE_EVENT(4, sch->dev.bus_id); orb = &to_io_private(sch)->orb; /* sch is always under 2G. */ - orb->intparm = (u32)(addr_t)sch; - orb->fmt = 1; + orb->cmd.intparm = (u32)(addr_t)sch; + orb->cmd.fmt = 1; - orb->pfch = sch->options.prefetch == 0; - orb->spnd = sch->options.suspend; - orb->ssic = sch->options.suspend && sch->options.inter; - orb->lpm = (lpm != 0) ? lpm : sch->lpm; + orb->cmd.pfch = sch->options.prefetch == 0; + orb->cmd.spnd = sch->options.suspend; + orb->cmd.ssic = sch->options.suspend && sch->options.inter; + orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm; #ifdef CONFIG_64BIT /* * for 64 bit we always support 64 bit IDAWs with 4k page size only */ - orb->c64 = 1; - orb->i2k = 0; + orb->cmd.c64 = 1; + orb->cmd.i2k = 0; #endif - orb->key = key >> 4; + orb->cmd.key = key >> 4; /* issue "Start Subchannel" */ - orb->cpa = (__u32) __pa(cpa); + orb->cmd.cpa = (__u32) __pa(cpa); ccode = ssch(sch->schid, orb); /* process condition code */ @@ -1067,3 +1068,61 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) iplinfo->is_qdio = schib.pmcw.qf; return 0; } + +/** + * cio_tm_start_key - perform start function + * @sch: subchannel on which to perform the start function + * @tcw: transport-command word to be started + * @lpm: mask of paths to use + * @key: storage key to use for storage access + * + * Start the tcw on the given subchannel. Return zero on success, non-zero + * otherwise. + */ +int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key) +{ + int cc; + union orb *orb = &to_io_private(sch)->orb; + + memset(orb, 0, sizeof(union orb)); + orb->tm.intparm = (u32) (addr_t) sch; + orb->tm.key = key >> 4; + orb->tm.b = 1; + orb->tm.lpm = lpm ? lpm : sch->lpm; + orb->tm.tcw = (u32) (addr_t) tcw; + cc = ssch(sch->schid, orb); + switch (cc) { + case 0: + return 0; + case 1: + case 2: + return -EBUSY; + default: + return cio_start_handle_notoper(sch, lpm); + } +} + +/** + * cio_tm_intrg - perform interrogate function + * @sch - subchannel on which to perform the interrogate function + * + * If the specified subchannel is running in transport-mode, perform the + * interrogate function. Return zero on success, non-zero otherwie. + */ +int cio_tm_intrg(struct subchannel *sch) +{ + int cc; + + if (!to_io_private(sch)->orb.tm.b) + return -EINVAL; + cc = xsch(sch->schid); + switch (cc) { + case 0: + case 2: + return 0; + case 1: + return -EBUSY; + default: + return -ENODEV; + } +} diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index f7a0cb9fac9..49ee6395116 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "chsc.h" #include "schid.h" @@ -100,6 +102,9 @@ extern int cio_set_options (struct subchannel *, int); extern int cio_get_options (struct subchannel *); extern int cio_modify (struct subchannel *); +int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); +int cio_tm_intrg(struct subchannel *sch); + int cio_create_sch_lock(struct subchannel *); void do_adapter_IO(void); void do_IRQ(struct pt_regs *); diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index dc9373031af..cd31bb5177e 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -39,31 +39,43 @@ static void ccw_timeout_log(struct ccw_device *cdev) struct schib schib; struct subchannel *sch; struct io_subchannel_private *private; + union orb *orb; int cc; sch = to_subchannel(cdev->dev.parent); private = to_io_private(sch); + orb = &private->orb; cc = stsch(sch->schid, &schib); printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " "device information:\n", get_clock()); printk(KERN_WARNING "cio: orb:\n"); print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, - &private->orb, sizeof(private->orb), 0); + orb, sizeof(*orb), 0); printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id); printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id); printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, " "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm); - if ((void *)(addr_t)private->orb.cpa == &private->sense_ccw || - (void *)(addr_t)private->orb.cpa == cdev->private->iccws) - printk(KERN_WARNING "cio: last channel program (intern):\n"); - else - printk(KERN_WARNING "cio: last channel program:\n"); - - print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, - (void *)(addr_t)private->orb.cpa, - sizeof(struct ccw1), 0); + if (orb->tm.b) { + printk(KERN_WARNING "cio: orb indicates transport mode\n"); + printk(KERN_WARNING "cio: last tcw:\n"); + print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, + (void *)(addr_t)orb->tm.tcw, + sizeof(struct tcw), 0); + } else { + printk(KERN_WARNING "cio: orb indicates command mode\n"); + if ((void *)(addr_t)orb->cmd.cpa == &private->sense_ccw || + (void *)(addr_t)orb->cmd.cpa == cdev->private->iccws) + printk(KERN_WARNING "cio: last channel program " + "(intern):\n"); + else + printk(KERN_WARNING "cio: last channel program:\n"); + + print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, + (void *)(addr_t)orb->cmd.cpa, + sizeof(struct ccw1), 0); + } printk(KERN_WARNING "cio: ccw device state: %d\n", cdev->private->state); printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc); @@ -135,10 +147,13 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) /* Stage 1: cancel io. */ if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) && !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { - ret = cio_cancel(sch); - if (ret != -EINVAL) - return ret; - /* cancel io unsuccessful. From now on it is asynchronous. */ + if (!scsw_is_tm(&sch->schib.scsw)) { + ret = cio_cancel(sch); + if (ret != -EINVAL) + return ret; + } + /* cancel io unsuccessful or not applicable (transport mode). + * Continue with asynchronous instructions. */ cdev->private->iretry = 3; /* 3 halt retries. */ } if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { @@ -751,11 +766,13 @@ static void ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) { struct irb *irb; + int is_cmd; irb = (struct irb *) __LC_IRB; + is_cmd = !scsw_is_tm(&irb->scsw); /* Check for unsolicited interrupt. */ if (!scsw_is_solicited(&irb->scsw)) { - if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && + if (is_cmd && (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && !irb->esw.esw0.erw.cons) { /* Unit check but no sense data. Need basic sense. */ if (ccw_device_do_sense(cdev, irb) != 0) @@ -774,7 +791,7 @@ call_handler_unsol: } /* Accumulate status and find out if a basic sense is needed. */ ccw_device_accumulate_irb(cdev, irb); - if (cdev->private->flags.dosense) { + if (is_cmd && cdev->private->flags.dosense) { if (ccw_device_do_sense(cdev, irb) == 0) { cdev->private->state = DEV_STATE_W4SENSE; } diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 5214b2b5425..1bdaa614e34 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -237,7 +237,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) if (irb->scsw.cmd.cc == 3) { u8 lpm; - lpm = to_io_private(sch)->orb.lpm; + lpm = to_io_private(sch)->orb.cmd.lpm; if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x " "on subchannel 0.%x.%04x is " diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 10f72c5c005..ee1a28310fb 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "cio.h" #include "cio_debug.h" @@ -569,6 +570,122 @@ void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id) } EXPORT_SYMBOL(ccw_device_get_id); +/** + * ccw_device_tm_start_key - perform start function + * @cdev: ccw device on which to perform the start function + * @tcw: transport-command word to be started + * @intparm: user defined parameter to be passed to the interrupt handler + * @lpm: mask of paths to use + * @key: storage key to use for storage access + * + * Start the tcw on the given ccw device. Return zero on success, non-zero + * otherwise. + */ +int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, + unsigned long intparm, u8 lpm, u8 key) +{ + struct subchannel *sch; + int rc; + + sch = to_subchannel(cdev->dev.parent); + if (cdev->private->state != DEV_STATE_ONLINE) + return -EIO; + /* Adjust requested path mask to excluded varied off paths. */ + if (lpm) { + lpm &= sch->opm; + if (lpm == 0) + return -EACCES; + } + rc = cio_tm_start_key(sch, tcw, lpm, key); + if (rc == 0) + cdev->private->intparm = intparm; + return rc; +} +EXPORT_SYMBOL(ccw_device_tm_start_key); + +/** + * ccw_device_tm_start_timeout_key - perform start function + * @cdev: ccw device on which to perform the start function + * @tcw: transport-command word to be started + * @intparm: user defined parameter to be passed to the interrupt handler + * @lpm: mask of paths to use + * @key: storage key to use for storage access + * @expires: time span in jiffies after which to abort request + * + * Start the tcw on the given ccw device. Return zero on success, non-zero + * otherwise. + */ +int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw, + unsigned long intparm, u8 lpm, u8 key, + int expires) +{ + int ret; + + ccw_device_set_timeout(cdev, expires); + ret = ccw_device_tm_start_key(cdev, tcw, intparm, lpm, key); + if (ret != 0) + ccw_device_set_timeout(cdev, 0); + return ret; +} +EXPORT_SYMBOL(ccw_device_tm_start_timeout_key); + +/** + * ccw_device_tm_start - perform start function + * @cdev: ccw device on which to perform the start function + * @tcw: transport-command word to be started + * @intparm: user defined parameter to be passed to the interrupt handler + * @lpm: mask of paths to use + * + * Start the tcw on the given ccw device. Return zero on success, non-zero + * otherwise. + */ +int ccw_device_tm_start(struct ccw_device *cdev, struct tcw *tcw, + unsigned long intparm, u8 lpm) +{ + return ccw_device_tm_start_key(cdev, tcw, intparm, lpm, + PAGE_DEFAULT_KEY); +} +EXPORT_SYMBOL(ccw_device_tm_start); + +/** + * ccw_device_tm_start_timeout - perform start function + * @cdev: ccw device on which to perform the start function + * @tcw: transport-command word to be started + * @intparm: user defined parameter to be passed to the interrupt handler + * @lpm: mask of paths to use + * @expires: time span in jiffies after which to abort request + * + * Start the tcw on the given ccw device. Return zero on success, non-zero + * otherwise. + */ +int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw, + unsigned long intparm, u8 lpm, int expires) +{ + return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm, + PAGE_DEFAULT_KEY, expires); +} +EXPORT_SYMBOL(ccw_device_tm_start_timeout); + +/** + * ccw_device_tm_intrg - perform interrogate function + * @cdev: ccw device on which to perform the interrogate function + * + * Perform an interrogate function on the given ccw device. Return zero on + * success, non-zero otherwise. + */ +int ccw_device_tm_intrg(struct ccw_device *cdev) +{ + struct subchannel *sch = to_subchannel(cdev->dev.parent); + + if (cdev->private->state != DEV_STATE_ONLINE) + return -EIO; + if (!scsw_is_tm(&sch->schib.scsw) || + !(scsw_actl(&sch->schib.scsw) | SCSW_ACTL_START_PEND)) + return -EINVAL; + return cio_tm_intrg(sch); +} +EXPORT_SYMBOL(ccw_device_tm_intrg); + // FIXME: these have to go: int diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 22a711bb544..86bc94eb607 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -158,7 +158,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) if (irb->scsw.cmd.cc == 3) { u8 lpm; - lpm = to_io_private(sch)->orb.lpm; + lpm = to_io_private(sch)->orb.cmd.lpm; CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, diff --git a/drivers/s390/cio/fcx.c b/drivers/s390/cio/fcx.c new file mode 100644 index 00000000000..61677dfbdc9 --- /dev/null +++ b/drivers/s390/cio/fcx.c @@ -0,0 +1,350 @@ +/* + * Functions for assembling fcx enabled I/O control blocks. + * + * Copyright IBM Corp. 2008 + * Author(s): Peter Oberparleiter + */ + +#include +#include +#include +#include +#include +#include +#include +#include "cio.h" + +/** + * tcw_get_intrg - return pointer to associated interrogate tcw + * @tcw: pointer to the original tcw + * + * Return a pointer to the interrogate tcw associated with the specified tcw + * or %NULL if there is no associated interrogate tcw. + */ +struct tcw *tcw_get_intrg(struct tcw *tcw) +{ + return (struct tcw *) ((addr_t) tcw->intrg); +} +EXPORT_SYMBOL(tcw_get_intrg); + +/** + * tcw_get_data - return pointer to input/output data associated with tcw + * @tcw: pointer to the tcw + * + * Return the input or output data address specified in the tcw depending + * on whether the r-bit or the w-bit is set. If neither bit is set, return + * %NULL. + */ +void *tcw_get_data(struct tcw *tcw) +{ + if (tcw->r) + return (void *) ((addr_t) tcw->input); + if (tcw->w) + return (void *) ((addr_t) tcw->output); + return NULL; +} +EXPORT_SYMBOL(tcw_get_data); + +/** + * tcw_get_tccb - return pointer to tccb associated with tcw + * @tcw: pointer to the tcw + * + * Return pointer to the tccb associated with this tcw. + */ +struct tccb *tcw_get_tccb(struct tcw *tcw) +{ + return (struct tccb *) ((addr_t) tcw->tccb); +} +EXPORT_SYMBOL(tcw_get_tccb); + +/** + * tcw_get_tsb - return pointer to tsb associated with tcw + * @tcw: pointer to the tcw + * + * Return pointer to the tsb associated with this tcw. + */ +struct tsb *tcw_get_tsb(struct tcw *tcw) +{ + return (struct tsb *) ((addr_t) tcw->tsb); +} +EXPORT_SYMBOL(tcw_get_tsb); + +/** + * tcw_init - initialize tcw data structure + * @tcw: pointer to the tcw to be initialized + * @r: initial value of the r-bit + * @w: initial value of the w-bit + * + * Initialize all fields of the specified tcw data structure with zero and + * fill in the format, flags, r and w fields. + */ +void tcw_init(struct tcw *tcw, int r, int w) +{ + memset(tcw, 0, sizeof(struct tcw)); + tcw->format = TCW_FORMAT_DEFAULT; + tcw->flags = TCW_FLAGS_TIDAW_FORMAT(TCW_TIDAW_FORMAT_DEFAULT); + if (r) + tcw->r = 1; + if (w) + tcw->w = 1; +} +EXPORT_SYMBOL(tcw_init); + +static inline size_t tca_size(struct tccb *tccb) +{ + return tccb->tcah.tcal - 12; +} + +static u32 calc_dcw_count(struct tccb *tccb) +{ + int offset; + struct dcw *dcw; + u32 count = 0; + size_t size; + + size = tca_size(tccb); + for (offset = 0; offset < size;) { + dcw = (struct dcw *) &tccb->tca[offset]; + count += dcw->count; + if (!(dcw->flags & DCW_FLAGS_CC)) + break; + offset += sizeof(struct dcw) + ALIGN((int) dcw->cd_count, 4); + } + return count; +} + +static u32 calc_cbc_size(struct tidaw *tidaw, int num) +{ + int i; + u32 cbc_data; + u32 cbc_count = 0; + u64 data_count = 0; + + for (i = 0; i < num; i++) { + if (tidaw[i].flags & TIDAW_FLAGS_LAST) + break; + /* TODO: find out if padding applies to total of data + * transferred or data transferred by this tidaw. Assumption: + * applies to total. */ + data_count += tidaw[i].count; + if (tidaw[i].flags & TIDAW_FLAGS_INSERT_CBC) { + cbc_data = 4 + ALIGN(data_count, 4) - data_count; + cbc_count += cbc_data; + data_count += cbc_data; + } + } + return cbc_count; +} + +/** + * tcw_finalize - finalize tcw length fields and tidaw list + * @tcw: pointer to the tcw + * @num_tidaws: the number of tidaws used to address input/output data or zero + * if no tida is used + * + * Calculate the input-/output-count and tccbl field in the tcw, add a + * tcat the tccb and terminate the data tidaw list if used. + * + * Note: in case input- or output-tida is used, the tidaw-list must be stored + * in contiguous storage (no ttic). The tcal field in the tccb must be + * up-to-date. + */ +void tcw_finalize(struct tcw *tcw, int num_tidaws) +{ + struct tidaw *tidaw; + struct tccb *tccb; + struct tccb_tcat *tcat; + u32 count; + + /* Terminate tidaw list. */ + tidaw = tcw_get_data(tcw); + if (num_tidaws > 0) + tidaw[num_tidaws - 1].flags |= TIDAW_FLAGS_LAST; + /* Add tcat to tccb. */ + tccb = tcw_get_tccb(tcw); + tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; + memset(tcat, 0, sizeof(tcat)); + /* Calculate tcw input/output count and tcat transport count. */ + count = calc_dcw_count(tccb); + if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) + count += calc_cbc_size(tidaw, num_tidaws); + if (tcw->r) + tcw->input_count = count; + else if (tcw->w) + tcw->output_count = count; + tcat->count = ALIGN(count, 4) + 4; + /* Calculate tccbl. */ + tcw->tccbl = (sizeof(struct tccb) + tca_size(tccb) + + sizeof(struct tccb_tcat) - 20) >> 2; +} +EXPORT_SYMBOL(tcw_finalize); + +/** + * tcw_set_intrg - set the interrogate tcw address of a tcw + * @tcw: the tcw address + * @intrg_tcw: the address of the interrogate tcw + * + * Set the address of the interrogate tcw in the specified tcw. + */ +void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw) +{ + tcw->intrg = (u32) ((addr_t) intrg_tcw); +} +EXPORT_SYMBOL(tcw_set_intrg); + +/** + * tcw_set_data - set data address and tida flag of a tcw + * @tcw: the tcw address + * @data: the data address + * @use_tidal: zero of the data address specifies a contiguous block of data, + * non-zero if it specifies a list if tidaws. + * + * Set the input/output data address of a tcw (depending on the value of the + * r-flag and w-flag). If @use_tidal is non-zero, the corresponding tida flag + * is set as well. + */ +void tcw_set_data(struct tcw *tcw, void *data, int use_tidal) +{ + if (tcw->r) { + tcw->input = (u64) ((addr_t) data); + if (use_tidal) + tcw->flags |= TCW_FLAGS_INPUT_TIDA; + } else if (tcw->w) { + tcw->output = (u64) ((addr_t) data); + if (use_tidal) + tcw->flags |= TCW_FLAGS_OUTPUT_TIDA; + } +} +EXPORT_SYMBOL(tcw_set_data); + +/** + * tcw_set_tccb - set tccb address of a tcw + * @tcw: the tcw address + * @tccb: the tccb address + * + * Set the address of the tccb in the specified tcw. + */ +void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb) +{ + tcw->tccb = (u64) ((addr_t) tccb); +} +EXPORT_SYMBOL(tcw_set_tccb); + +/** + * tcw_set_tsb - set tsb address of a tcw + * @tcw: the tcw address + * @tsb: the tsb address + * + * Set the address of the tsb in the specified tcw. + */ +void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb) +{ + tcw->tsb = (u64) ((addr_t) tsb); +} +EXPORT_SYMBOL(tcw_set_tsb); + +/** + * tccb_init - initialize tccb + * @tccb: the tccb address + * @size: the maximum size of the tccb + * @sac: the service-action-code to be user + * + * Initialize the header of the specified tccb by resetting all values to zero + * and filling in defaults for format, sac and initial tcal fields. + */ +void tccb_init(struct tccb *tccb, size_t size, u32 sac) +{ + memset(tccb, 0, size); + tccb->tcah.format = TCCB_FORMAT_DEFAULT; + tccb->tcah.sac = sac; + tccb->tcah.tcal = 12; +} +EXPORT_SYMBOL(tccb_init); + +/** + * tsb_init - initialize tsb + * @tsb: the tsb address + * + * Initialize the specified tsb by resetting all values to zero. + */ +void tsb_init(struct tsb *tsb) +{ + memset(tsb, 0, sizeof(tsb)); +} +EXPORT_SYMBOL(tsb_init); + +/** + * tccb_add_dcw - add a dcw to the tccb + * @tccb: the tccb address + * @tccb_size: the maximum tccb size + * @cmd: the dcw command + * @flags: flags for the dcw + * @cd: pointer to control data for this dcw or NULL if none is required + * @cd_count: number of control data bytes for this dcw + * @count: number of data bytes for this dcw + * + * Add a new dcw to the specified tccb by writing the dcw information specified + * by @cmd, @flags, @cd, @cd_count and @count to the tca of the tccb. Return + * a pointer to the newly added dcw on success or -%ENOSPC if the new dcw + * would exceed the available space as defined by @tccb_size. + * + * Note: the tcal field of the tccb header will be updates to reflect added + * content. + */ +struct dcw *tccb_add_dcw(struct tccb *tccb, size_t tccb_size, u8 cmd, u8 flags, + void *cd, u8 cd_count, u32 count) +{ + struct dcw *dcw; + int size; + int tca_offset; + + /* Check for space. */ + tca_offset = tca_size(tccb); + size = ALIGN(sizeof(struct dcw) + cd_count, 4); + if (sizeof(struct tccb_tcah) + tca_offset + size + + sizeof(struct tccb_tcat) > tccb_size) + return ERR_PTR(-ENOSPC); + /* Add dcw to tca. */ + dcw = (struct dcw *) &tccb->tca[tca_offset]; + memset(dcw, 0, size); + dcw->cmd = cmd; + dcw->flags = flags; + dcw->count = count; + dcw->cd_count = cd_count; + if (cd) + memcpy(&dcw->cd[0], cd, cd_count); + tccb->tcah.tcal += size; + return dcw; +} +EXPORT_SYMBOL(tccb_add_dcw); + +/** + * tcw_add_tidaw - add a tidaw to a tcw + * @tcw: the tcw address + * @num_tidaws: the current number of tidaws + * @flags: flags for the new tidaw + * @addr: address value for the new tidaw + * @count: count value for the new tidaw + * + * Add a new tidaw to the input/output data tidaw-list of the specified tcw + * (depending on the value of the r-flag and w-flag) and return a pointer to + * the new tidaw. + * + * Note: the tidaw-list is assumed to be contiguous with no ttics. The caller + * must ensure that there is enough space for the new tidaw. The last-tidaw + * flag for the last tidaw in the list will be set by tcw_finalize. + */ +struct tidaw *tcw_add_tidaw(struct tcw *tcw, int num_tidaws, u8 flags, + void *addr, u32 count) +{ + struct tidaw *tidaw; + + /* Add tidaw to tidaw-list. */ + tidaw = ((struct tidaw *) tcw_get_data(tcw)) + num_tidaws; + memset(tidaw, 0, sizeof(struct tidaw)); + tidaw->flags = flags; + tidaw->count = count; + tidaw->addr = (u64) ((addr_t) addr); + return tidaw; +} +EXPORT_SYMBOL(tcw_add_tidaw); diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 8c613160bfc..b774960e76a 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -4,9 +4,9 @@ #include "schid.h" /* - * operation request block + * command-mode operation request block */ -struct orb { +struct cmd_orb { u32 intparm; /* interruption parameter */ u32 key : 4; /* flags, like key, suspend control, etc. */ u32 spnd : 1; /* suspend control */ @@ -28,8 +28,36 @@ struct orb { u32 cpa; /* channel program address */ } __attribute__ ((packed, aligned(4))); +/* + * transport-mode operation request block + */ +struct tm_orb { + u32 intparm; + u32 key:4; + u32 :9; + u32 b:1; + u32 :2; + u32 lpm:8; + u32 :7; + u32 x:1; + u32 tcw; + u32 prio:8; + u32 :8; + u32 rsvpgm:8; + u32 :8; + u32 :32; + u32 :32; + u32 :32; + u32 :32; +} __attribute__ ((packed, aligned(4))); + +union orb { + struct cmd_orb cmd; + struct tm_orb tm; +} __attribute__ ((packed, aligned(4))); + struct io_subchannel_private { - struct orb orb; /* operation request block */ + union orb orb; /* operation request block */ struct ccw1 sense_ccw; /* static ccw for sense command */ } __attribute__ ((aligned(8))); @@ -95,16 +123,18 @@ struct ccw_device_private { void *cmb_wait; /* deferred cmb enable/disable */ }; -static inline int ssch(struct subchannel_id schid, volatile struct orb *addr) +static inline int ssch(struct subchannel_id schid, volatile union orb *addr) { register struct subchannel_id reg1 asm("1") = schid; - int ccode; + int ccode = -EIO; asm volatile( " ssch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } diff --git a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h index 066aa70518c..ba007d8df94 100644 --- a/include/asm-s390/ccwdev.h +++ b/include/asm-s390/ccwdev.h @@ -12,6 +12,7 @@ #include #include +#include /* structs from asm/cio.h */ struct irb; @@ -157,6 +158,17 @@ extern int ccw_device_start_timeout_key(struct ccw_device *, struct ccw1 *, extern int ccw_device_resume(struct ccw_device *); extern int ccw_device_halt(struct ccw_device *, unsigned long); extern int ccw_device_clear(struct ccw_device *, unsigned long); +int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, + unsigned long intparm, u8 lpm, u8 key); +int ccw_device_tm_start_key(struct ccw_device *, struct tcw *, + unsigned long, u8, u8); +int ccw_device_tm_start_timeout_key(struct ccw_device *, struct tcw *, + unsigned long, u8, u8, int); +int ccw_device_tm_start(struct ccw_device *, struct tcw *, + unsigned long, u8); +int ccw_device_tm_start_timeout(struct ccw_device *, struct tcw *, + unsigned long, u8, int); +int ccw_device_tm_intrg(struct ccw_device *cdev); extern int ccw_device_set_online(struct ccw_device *cdev); extern int ccw_device_set_offline(struct ccw_device *cdev); diff --git a/include/asm-s390/fcx.h b/include/asm-s390/fcx.h new file mode 100644 index 00000000000..8be1f3a5804 --- /dev/null +++ b/include/asm-s390/fcx.h @@ -0,0 +1,311 @@ +/* + * Functions for assembling fcx enabled I/O control blocks. + * + * Copyright IBM Corp. 2008 + * Author(s): Peter Oberparleiter + */ + +#ifndef _ASM_S390_FCX_H +#define _ASM_S390_FCX_H _ASM_S390_FCX_H + +#include + +#define TCW_FORMAT_DEFAULT 0 +#define TCW_TIDAW_FORMAT_DEFAULT 0 +#define TCW_FLAGS_INPUT_TIDA 1 << (23 - 5) +#define TCW_FLAGS_TCCB_TIDA 1 << (23 - 6) +#define TCW_FLAGS_OUTPUT_TIDA 1 << (23 - 7) +#define TCW_FLAGS_TIDAW_FORMAT(x) ((x) & 3) << (23 - 9) +#define TCW_FLAGS_GET_TIDAW_FORMAT(x) (((x) >> (23 - 9)) & 3) + +/** + * struct tcw - Transport Control Word (TCW) + * @format: TCW format + * @flags: TCW flags + * @tccbl: Transport-Command-Control-Block Length + * @r: Read Operations + * @w: Write Operations + * @output: Output-Data Address + * @input: Input-Data Address + * @tsb: Transport-Status-Block Address + * @tccb: Transport-Command-Control-Block Address + * @output_count: Output Count + * @input_count: Input Count + * @intrg: Interrogate TCW Address + */ +struct tcw { + u32 format:2; + u32 :6; + u32 flags:24; + u32 :8; + u32 tccbl:6; + u32 r:1; + u32 w:1; + u32 :16; + u64 output; + u64 input; + u64 tsb; + u64 tccb; + u32 output_count; + u32 input_count; + u32 :32; + u32 :32; + u32 :32; + u32 intrg; +} __attribute__ ((packed, aligned(64))); + +#define TIDAW_FLAGS_LAST 1 << (7 - 0) +#define TIDAW_FLAGS_SKIP 1 << (7 - 1) +#define TIDAW_FLAGS_DATA_INT 1 << (7 - 2) +#define TIDAW_FLAGS_TTIC 1 << (7 - 3) +#define TIDAW_FLAGS_INSERT_CBC 1 << (7 - 4) + +/** + * struct tidaw - Transport-Indirect-Addressing Word (TIDAW) + * @flags: TIDAW flags. Can be an arithmetic OR of the following constants: + * %TIDAW_FLAGS_LAST, %TIDAW_FLAGS_SKIP, %TIDAW_FLAGS_DATA_INT, + * %TIDAW_FLAGS_TTIC, %TIDAW_FLAGS_INSERT_CBC + * @count: Count + * @addr: Address + */ +struct tidaw { + u32 flags:8; + u32 :24; + u32 count; + u64 addr; +} __attribute__ ((packed, aligned(16))); + +/** + * struct tsa_iostat - I/O-Status Transport-Status Area (IO-Stat TSA) + * @dev_time: Device Time + * @def_time: Defer Time + * @queue_time: Queue Time + * @dev_busy_time: Device-Busy Time + * @dev_act_time: Device-Active-Only Time + * @sense: Sense Data (if present) + */ +struct tsa_iostat { + u32 dev_time; + u32 def_time; + u32 queue_time; + u32 dev_busy_time; + u32 dev_act_time; + u8 sense[32]; +} __attribute__ ((packed)); + +/** + * struct tsa_ddpcs - Device-Detected-Program-Check Transport-Status Area (DDPC TSA) + * @rc: Reason Code + * @rcq: Reason Code Qualifier + * @sense: Sense Data (if present) + */ +struct tsa_ddpc { + u32 :24; + u32 rc:8; + u8 rcq[16]; + u8 sense[32]; +} __attribute__ ((packed)); + +#define TSA_INTRG_FLAGS_CU_STATE_VALID 1 << (7 - 0) +#define TSA_INTRG_FLAGS_DEV_STATE_VALID 1 << (7 - 1) +#define TSA_INTRG_FLAGS_OP_STATE_VALID 1 << (7 - 2) + +/** + * struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA) + * @format: Format + * @flags: Flags. Can be an arithmetic OR of the following constants: + * %TSA_INTRG_FLAGS_CU_STATE_VALID, %TSA_INTRG_FLAGS_DEV_STATE_VALID, + * %TSA_INTRG_FLAGS_OP_STATE_VALID + * @cu_state: Controle-Unit State + * @dev_state: Device State + * @op_state: Operation State + * @sd_info: State-Dependent Information + * @dl_id: Device-Level Identifier + * @dd_data: Device-Dependent Data + */ +struct tsa_intrg { + u32 format:8; + u32 flags:8; + u32 cu_state:8; + u32 dev_state:8; + u32 op_state:8; + u32 :24; + u8 sd_info[12]; + u32 dl_id; + u8 dd_data[28]; +} __attribute__ ((packed)); + +#define TSB_FORMAT_NONE 0 +#define TSB_FORMAT_IOSTAT 1 +#define TSB_FORMAT_DDPC 2 +#define TSB_FORMAT_INTRG 3 + +#define TSB_FLAGS_DCW_OFFSET_VALID 1 << (7 - 0) +#define TSB_FLAGS_COUNT_VALID 1 << (7 - 1) +#define TSB_FLAGS_CACHE_MISS 1 << (7 - 2) +#define TSB_FLAGS_TIME_VALID 1 << (7 - 3) +#define TSB_FLAGS_FORMAT(x) ((x) & 7) +#define TSB_FORMAT(t) ((t)->flags & 7) + +/** + * struct tsb - Transport-Status Block (TSB) + * @length: Length + * @flags: Flags. Can be an arithmetic OR of the following constants: + * %TSB_FLAGS_DCW_OFFSET_VALID, %TSB_FLAGS_COUNT_VALID, %TSB_FLAGS_CACHE_MISS, + * %TSB_FLAGS_TIME_VALID + * @dcw_offset: DCW Offset + * @count: Count + * @tsa: Transport-Status-Area + */ +struct tsb { + u32 length:8; + u32 flags:8; + u32 dcw_offset:16; + u32 count; + u32 :32; + union { + struct tsa_iostat iostat; + struct tsa_ddpc ddpc; + struct tsa_intrg intrg; + } __attribute__ ((packed)) tsa; +} __attribute__ ((packed, aligned(8))); + +#define DCW_INTRG_FORMAT_DEFAULT 0 + +#define DCW_INTRG_RC_UNSPECIFIED 0 +#define DCW_INTRG_RC_TIMEOUT 1 + +#define DCW_INTRG_RCQ_UNSPECIFIED 0 +#define DCW_INTRG_RCQ_PRIMARY 1 +#define DCW_INTRG_RCQ_SECONDARY 2 + +#define DCW_INTRG_FLAGS_MPM 1 < (7 - 0) +#define DCW_INTRG_FLAGS_PPR 1 < (7 - 1) +#define DCW_INTRG_FLAGS_CRIT 1 < (7 - 2) + +/** + * struct dcw_intrg_data - Interrogate DCW data + * @format: Format. Should be %DCW_INTRG_FORMAT_DEFAULT + * @rc: Reason Code. Can be one of %DCW_INTRG_RC_UNSPECIFIED, + * %DCW_INTRG_RC_TIMEOUT + * @rcq: Reason Code Qualifier: Can be one of %DCW_INTRG_RCQ_UNSPECIFIED, + * %DCW_INTRG_RCQ_PRIMARY, %DCW_INTRG_RCQ_SECONDARY + * @lpm: Logical-Path Mask + * @pam: Path-Available Mask + * @pim: Path-Installed Mask + * @timeout: Timeout + * @flags: Flags. Can be an arithmetic OR of %DCW_INTRG_FLAGS_MPM, + * %DCW_INTRG_FLAGS_PPR, %DCW_INTRG_FLAGS_CRIT + * @time: Time + * @prog_id: Program Identifier + * @prog_data: Program-Dependent Data + */ +struct dcw_intrg_data { + u32 format:8; + u32 rc:8; + u32 rcq:8; + u32 lpm:8; + u32 pam:8; + u32 pim:8; + u32 timeout:16; + u32 flags:8; + u32 :24; + u32 :32; + u64 time; + u64 prog_id; + u8 prog_data[0]; +} __attribute__ ((packed)); + +#define DCW_FLAGS_CC 1 << (7 - 1) + +#define DCW_CMD_WRITE 0x01 +#define DCW_CMD_READ 0x02 +#define DCW_CMD_CONTROL 0x03 +#define DCW_CMD_SENSE 0x04 +#define DCW_CMD_SENSE_ID 0xe4 +#define DCW_CMD_INTRG 0x40 + +/** + * struct dcw - Device-Command Word (DCW) + * @cmd: Command Code. Can be one of %DCW_CMD_WRITE, %DCW_CMD_READ, + * %DCW_CMD_CONTROL, %DCW_CMD_SENSE, %DCW_CMD_SENSE_ID, %DCW_CMD_INTRG + * @flags: Flags. Can be an arithmetic OR of %DCW_FLAGS_CC + * @cd_count: Control-Data Count + * @count: Count + * @cd: Control Data + */ +struct dcw { + u32 cmd:8; + u32 flags:8; + u32 :8; + u32 cd_count:8; + u32 count; + u8 cd[0]; +} __attribute__ ((packed)); + +#define TCCB_FORMAT_DEFAULT 0x7f +#define TCCB_MAX_DCW 30 +#define TCCB_MAX_SIZE (sizeof(struct tccb_tcah) + \ + TCCB_MAX_DCW * sizeof(struct dcw) + \ + sizeof(struct tccb_tcat)) +#define TCCB_SAC_DEFAULT 0xf901 +#define TCCB_SAC_INTRG 0xf902 + +/** + * struct tccb_tcah - Transport-Command-Area Header (TCAH) + * @format: Format. Should be %TCCB_FORMAT_DEFAULT + * @tcal: Transport-Command-Area Length + * @sac: Service-Action Code. Can be one of %TCCB_SAC_DEFAULT, %TCCB_SAC_INTRG + * @prio: Priority + */ +struct tccb_tcah { + u32 format:8; + u32 :24; + u32 :24; + u32 tcal:8; + u32 sac:16; + u32 :8; + u32 prio:8; + u32 :32; +} __attribute__ ((packed)); + +/** + * struct tccb_tcat - Transport-Command-Area Trailer (TCAT) + * @count: Transport Count + */ +struct tccb_tcat { + u32 :32; + u32 count; +} __attribute__ ((packed)); + +/** + * struct tccb - (partial) Transport-Command-Control Block (TCCB) + * @tcah: TCAH + * @tca: Transport-Command Area + */ +struct tccb { + struct tccb_tcah tcah; + u8 tca[0]; +} __attribute__ ((packed, aligned(8))); + +struct tcw *tcw_get_intrg(struct tcw *tcw); +void *tcw_get_data(struct tcw *tcw); +struct tccb *tcw_get_tccb(struct tcw *tcw); +struct tsb *tcw_get_tsb(struct tcw *tcw); + +void tcw_init(struct tcw *tcw, int r, int w); +void tcw_finalize(struct tcw *tcw, int num_tidaws); + +void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw); +void tcw_set_data(struct tcw *tcw, void *data, int use_tidal); +void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb); +void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb); + +void tccb_init(struct tccb *tccb, size_t tccb_size, u32 sac); +void tsb_init(struct tsb *tsb); +struct dcw *tccb_add_dcw(struct tccb *tccb, size_t tccb_size, u8 cmd, u8 flags, + void *cd, u8 cd_count, u32 count); +struct tidaw *tcw_add_tidaw(struct tcw *tcw, int num_tidaws, u8 flags, + void *addr, u32 count); + +#endif /* _ASM_S390_FCX_H */ -- GitLab From 23f626894765d4c03b72a0d21e44bc46f5ccd12b Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:58:52 +0200 Subject: [PATCH 1759/2509] [S390] cio: provide helper functions for fcx enabled I/O Provide functions which can be used to incrementally construct fcx enabled I/O control blocks. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/Makefile | 3 +- drivers/s390/cio/itcw.c | 327 ++++++++++++++++++++++++++++++++++++++ include/asm-s390/itcw.h | 30 ++++ 3 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 drivers/s390/cio/itcw.c create mode 100644 include/asm-s390/itcw.h diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index ee3c416243b..e199c927b7a 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -2,7 +2,8 @@ # Makefile for the S/390 common i/o drivers # -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o \ + itcw.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/itcw.c b/drivers/s390/cio/itcw.c new file mode 100644 index 00000000000..17da9ab932e --- /dev/null +++ b/drivers/s390/cio/itcw.c @@ -0,0 +1,327 @@ +/* + * Functions for incremental construction of fcx enabled I/O control blocks. + * + * Copyright IBM Corp. 2008 + * Author(s): Peter Oberparleiter + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct itcw - incremental tcw helper data type + * + * This structure serves as a handle for the incremental construction of a + * tcw and associated tccb, tsb, data tidaw-list plus an optional interrogate + * tcw and associated data. The data structures are contained inside a single + * contiguous buffer provided by the user. + * + * The itcw construction functions take care of overall data integrity: + * - reset unused fields to zero + * - fill in required pointers + * - ensure required alignment for data structures + * - prevent data structures to cross 4k-byte boundary where required + * - calculate tccb-related length fields + * - optionally provide ready-made interrogate tcw and associated structures + * + * Restrictions apply to the itcws created with these construction functions: + * - tida only supported for data address, not for tccb + * - only contiguous tidaw-lists (no ttic) + * - total number of bytes required per itcw may not exceed 4k bytes + * - either read or write operation (may not work with r=0 and w=0) + * + * Example: + * struct itcw *itcw; + * void *buffer; + * size_t size; + * + * size = itcw_calc_size(1, 2, 0); + * buffer = kmalloc(size, GFP_DMA); + * if (!buffer) + * return -ENOMEM; + * itcw = itcw_init(buffer, size, ITCW_OP_READ, 1, 2, 0); + * if (IS_ERR(itcw)) + * return PTR_ER(itcw); + * itcw_add_dcw(itcw, 0x2, 0, NULL, 0, 72); + * itcw_add_tidaw(itcw, 0, 0x30000, 20); + * itcw_add_tidaw(itcw, 0, 0x40000, 52); + * itcw_finalize(itcw); + * + */ +struct itcw { + struct tcw *tcw; + struct tcw *intrg_tcw; + int num_tidaws; + int max_tidaws; + int intrg_num_tidaws; + int intrg_max_tidaws; +}; + +/** + * itcw_get_tcw - return pointer to tcw associated with the itcw + * @itcw: address of the itcw + * + * Return pointer to the tcw associated with the itcw. + */ +struct tcw *itcw_get_tcw(struct itcw *itcw) +{ + return itcw->tcw; +} +EXPORT_SYMBOL(itcw_get_tcw); + +/** + * itcw_calc_size - return the size of an itcw with the given parameters + * @intrg: if non-zero, add an interrogate tcw + * @max_tidaws: maximum number of tidaws to be used for data addressing or zero + * if no tida is to be used. + * @intrg_max_tidaws: maximum number of tidaws to be used for data addressing + * by the interrogate tcw, if specified + * + * Calculate and return the number of bytes required to hold an itcw with the + * given parameters and assuming tccbs with maximum size. + * + * Note that the resulting size also contains bytes needed for alignment + * padding as well as padding to ensure that data structures don't cross a + * 4k-boundary where required. + */ +size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws) +{ + size_t len; + + /* Main data. */ + len = sizeof(struct itcw); + len += /* TCW */ sizeof(struct tcw) + /* TCCB */ TCCB_MAX_SIZE + + /* TSB */ sizeof(struct tsb) + + /* TIDAL */ max_tidaws * sizeof(struct tidaw); + /* Interrogate data. */ + if (intrg) { + len += /* TCW */ sizeof(struct tcw) + /* TCCB */ TCCB_MAX_SIZE + + /* TSB */ sizeof(struct tsb) + + /* TIDAL */ intrg_max_tidaws * sizeof(struct tidaw); + } + /* Maximum required alignment padding. */ + len += /* Initial TCW */ 63 + /* Interrogate TCCB */ 7; + /* Maximum padding for structures that may not cross 4k boundary. */ + if ((max_tidaws > 0) || (intrg_max_tidaws > 0)) + len += max(max_tidaws, intrg_max_tidaws) * + sizeof(struct tidaw) - 1; + return len; +} +EXPORT_SYMBOL(itcw_calc_size); + +#define CROSS4K(x, l) (((x) & ~4095) != ((x + l) & ~4095)) + +static inline void *fit_chunk(addr_t *start, addr_t end, size_t len, + int align, int check_4k) +{ + addr_t addr; + + addr = ALIGN(*start, align); + if (check_4k && CROSS4K(addr, len)) { + addr = ALIGN(addr, 4096); + addr = ALIGN(addr, align); + } + if (addr + len > end) + return ERR_PTR(-ENOSPC); + *start = addr + len; + return (void *) addr; +} + +/** + * itcw_init - initialize incremental tcw data structure + * @buffer: address of buffer to use for data structures + * @size: number of bytes in buffer + * @op: %ITCW_OP_READ for a read operation tcw, %ITCW_OP_WRITE for a write + * operation tcw + * @intrg: if non-zero, add and initialize an interrogate tcw + * @max_tidaws: maximum number of tidaws to be used for data addressing or zero + * if no tida is to be used. + * @intrg_max_tidaws: maximum number of tidaws to be used for data addressing + * by the interrogate tcw, if specified + * + * Prepare the specified buffer to be used as an incremental tcw, i.e. a + * helper data structure that can be used to construct a valid tcw by + * successive calls to other helper functions. Note: the buffer needs to be + * located below the 2G address limit. The resulting tcw has the following + * restrictions: + * - no tccb tidal + * - input/output tidal is contiguous (no ttic) + * - total data should not exceed 4k + * - tcw specifies either read or write operation + * + * On success, return pointer to the resulting incremental tcw data structure, + * ERR_PTR otherwise. + */ +struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg, + int max_tidaws, int intrg_max_tidaws) +{ + struct itcw *itcw; + void *chunk; + addr_t start; + addr_t end; + + /* Check for 2G limit. */ + start = (addr_t) buffer; + end = start + size; + if (end > (1 << 31)) + return ERR_PTR(-EINVAL); + memset(buffer, 0, size); + /* ITCW. */ + chunk = fit_chunk(&start, end, sizeof(struct itcw), 1, 0); + if (IS_ERR(chunk)) + return chunk; + itcw = chunk; + itcw->max_tidaws = max_tidaws; + itcw->intrg_max_tidaws = intrg_max_tidaws; + /* Main TCW. */ + chunk = fit_chunk(&start, end, sizeof(struct tcw), 64, 0); + if (IS_ERR(chunk)) + return chunk; + itcw->tcw = chunk; + tcw_init(itcw->tcw, (op == ITCW_OP_READ) ? 1 : 0, + (op == ITCW_OP_WRITE) ? 1 : 0); + /* Interrogate TCW. */ + if (intrg) { + chunk = fit_chunk(&start, end, sizeof(struct tcw), 64, 0); + if (IS_ERR(chunk)) + return chunk; + itcw->intrg_tcw = chunk; + tcw_init(itcw->intrg_tcw, 1, 0); + tcw_set_intrg(itcw->tcw, itcw->intrg_tcw); + } + /* Data TIDAL. */ + if (max_tidaws > 0) { + chunk = fit_chunk(&start, end, sizeof(struct tidaw) * + max_tidaws, 16, 1); + if (IS_ERR(chunk)) + return chunk; + tcw_set_data(itcw->tcw, chunk, 1); + } + /* Interrogate data TIDAL. */ + if (intrg && (intrg_max_tidaws > 0)) { + chunk = fit_chunk(&start, end, sizeof(struct tidaw) * + intrg_max_tidaws, 16, 1); + if (IS_ERR(chunk)) + return chunk; + tcw_set_data(itcw->intrg_tcw, chunk, 1); + } + /* TSB. */ + chunk = fit_chunk(&start, end, sizeof(struct tsb), 8, 0); + if (IS_ERR(chunk)) + return chunk; + tsb_init(chunk); + tcw_set_tsb(itcw->tcw, chunk); + /* Interrogate TSB. */ + if (intrg) { + chunk = fit_chunk(&start, end, sizeof(struct tsb), 8, 0); + if (IS_ERR(chunk)) + return chunk; + tsb_init(chunk); + tcw_set_tsb(itcw->intrg_tcw, chunk); + } + /* TCCB. */ + chunk = fit_chunk(&start, end, TCCB_MAX_SIZE, 8, 0); + if (IS_ERR(chunk)) + return chunk; + tccb_init(chunk, TCCB_MAX_SIZE, TCCB_SAC_DEFAULT); + tcw_set_tccb(itcw->tcw, chunk); + /* Interrogate TCCB. */ + if (intrg) { + chunk = fit_chunk(&start, end, TCCB_MAX_SIZE, 8, 0); + if (IS_ERR(chunk)) + return chunk; + tccb_init(chunk, TCCB_MAX_SIZE, TCCB_SAC_INTRG); + tcw_set_tccb(itcw->intrg_tcw, chunk); + tccb_add_dcw(chunk, TCCB_MAX_SIZE, DCW_CMD_INTRG, 0, NULL, + sizeof(struct dcw_intrg_data), 0); + tcw_finalize(itcw->intrg_tcw, 0); + } + return itcw; +} +EXPORT_SYMBOL(itcw_init); + +/** + * itcw_add_dcw - add a dcw to the itcw + * @itcw: address of the itcw + * @cmd: the dcw command + * @flags: flags for the dcw + * @cd: address of control data for this dcw or NULL if none is required + * @cd_count: number of control data bytes for this dcw + * @count: number of data bytes for this dcw + * + * Add a new dcw to the specified itcw by writing the dcw information specified + * by @cmd, @flags, @cd, @cd_count and @count to the tca of the tccb. Return + * a pointer to the newly added dcw on success or -%ENOSPC if the new dcw + * would exceed the available space. + * + * Note: the tcal field of the tccb header will be updated to reflect added + * content. + */ +struct dcw *itcw_add_dcw(struct itcw *itcw, u8 cmd, u8 flags, void *cd, + u8 cd_count, u32 count) +{ + return tccb_add_dcw(tcw_get_tccb(itcw->tcw), TCCB_MAX_SIZE, cmd, + flags, cd, cd_count, count); +} +EXPORT_SYMBOL(itcw_add_dcw); + +/** + * itcw_add_tidaw - add a tidaw to the itcw + * @itcw: address of the itcw + * @flags: flags for the new tidaw + * @addr: address value for the new tidaw + * @count: count value for the new tidaw + * + * Add a new tidaw to the input/output data tidaw-list of the specified itcw + * (depending on the value of the r-flag and w-flag). Return a pointer to + * the new tidaw on success or -%ENOSPC if the new tidaw would exceed the + * available space. + * + * Note: the tidaw-list is assumed to be contiguous with no ttics. The + * last-tidaw flag for the last tidaw in the list will be set by itcw_finalize. + */ +struct tidaw *itcw_add_tidaw(struct itcw *itcw, u8 flags, void *addr, u32 count) +{ + if (itcw->num_tidaws >= itcw->max_tidaws) + return ERR_PTR(-ENOSPC); + return tcw_add_tidaw(itcw->tcw, itcw->num_tidaws++, flags, addr, count); +} +EXPORT_SYMBOL(itcw_add_tidaw); + +/** + * itcw_set_data - set data address and tida flag of the itcw + * @itcw: address of the itcw + * @addr: the data address + * @use_tidal: zero of the data address specifies a contiguous block of data, + * non-zero if it specifies a list if tidaws. + * + * Set the input/output data address of the itcw (depending on the value of the + * r-flag and w-flag). If @use_tidal is non-zero, the corresponding tida flag + * is set as well. + */ +void itcw_set_data(struct itcw *itcw, void *addr, int use_tidal) +{ + tcw_set_data(itcw->tcw, addr, use_tidal); +} +EXPORT_SYMBOL(itcw_set_data); + +/** + * itcw_finalize - calculate length and count fields of the itcw + * @itcw: address of the itcw + * + * Calculate tcw input-/output-count and tccbl fields and add a tcat the tccb. + * In case input- or output-tida is used, the tidaw-list must be stored in + * continuous storage (no ttic). The tcal field in the tccb must be + * up-to-date. + */ +void itcw_finalize(struct itcw *itcw) +{ + tcw_finalize(itcw->tcw, itcw->num_tidaws); +} +EXPORT_SYMBOL(itcw_finalize); diff --git a/include/asm-s390/itcw.h b/include/asm-s390/itcw.h new file mode 100644 index 00000000000..a9bc5c36b32 --- /dev/null +++ b/include/asm-s390/itcw.h @@ -0,0 +1,30 @@ +/* + * Functions for incremental construction of fcx enabled I/O control blocks. + * + * Copyright IBM Corp. 2008 + * Author(s): Peter Oberparleiter + */ + +#ifndef _ASM_S390_ITCW_H +#define _ASM_S390_ITCW_H _ASM_S390_ITCW_H + +#include +#include + +#define ITCW_OP_READ 0 +#define ITCW_OP_WRITE 1 + +struct itcw; + +struct tcw *itcw_get_tcw(struct itcw *itcw); +size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws); +struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg, + int max_tidaws, int intrg_max_tidaws); +struct dcw *itcw_add_dcw(struct itcw *itcw, u8 cmd, u8 flags, void *cd, + u8 cd_count, u32 count); +struct tidaw *itcw_add_tidaw(struct itcw *itcw, u8 flags, void *addr, + u32 count); +void itcw_set_data(struct itcw *itcw, void *addr, int use_tidal); +void itcw_finalize(struct itcw *itcw); + +#endif /* _ASM_S390_ITCW_H */ -- GitLab From ae437a452ed20f9d13c1f17b0356201d54394efa Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 14 Jul 2008 09:58:53 +0200 Subject: [PATCH 1760/2509] [S390] cio: remove lock from ccw_device_oper_notify. Remove unnecessary ccw device locking inside ccw_device_oper_notify. Signed-off-by: Sebastian Ott Acked-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/device_fsm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index cd31bb5177e..8b5fe57fb2f 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -346,21 +346,15 @@ ccw_device_oper_notify(struct work_struct *work) struct ccw_device_private *priv; struct ccw_device *cdev; int ret; - unsigned long flags; priv = container_of(work, struct ccw_device_private, kick_work); cdev = priv->cdev; ret = ccw_device_notify(cdev, CIO_OPER); - spin_lock_irqsave(cdev->ccwlock, flags); if (ret) { /* Reenable channel measurements, if needed. */ - spin_unlock_irqrestore(cdev->ccwlock, flags); cmf_reenable(cdev); - spin_lock_irqsave(cdev->ccwlock, flags); wake_up(&cdev->private->wait_q); - } - spin_unlock_irqrestore(cdev->ccwlock, flags); - if (!ret) + } else /* Driver doesn't want device back. */ ccw_device_do_unreg_rereg(work); } -- GitLab From 63506c41986c4af9d4fd6f3490e98e335f3dc8f5 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:58:54 +0200 Subject: [PATCH 1761/2509] [S390] Introduce user_regset accessors for s390 Add the user_regset definitions for normal and compat processes, replace the dump_regs core dump cruft with the generic CORE_DUMP_USER_REGSET and replace binfmt_elf32.c with the generic compat_binfmt_elf.c implementation. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 1 + arch/s390/kernel/Makefile | 7 +- arch/s390/kernel/binfmt_elf32.c | 214 ------------------ arch/s390/kernel/compat_ptrace.h | 4 +- arch/s390/kernel/ptrace.c | 363 +++++++++++++++++++++++++++---- include/asm-s390/elf.h | 51 +---- include/asm-s390/processor.h | 14 +- include/asm-s390/ptrace.h | 15 ++ 8 files changed, 365 insertions(+), 304 deletions(-) delete mode 100644 arch/s390/kernel/binfmt_elf32.c diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 107e492cb47..a79820c3ab0 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -146,6 +146,7 @@ config MATHEMU config COMPAT bool "Kernel support for 31 bit emulation" depends on 64BIT + select COMPAT_BINFMT_ELF help Select this option if you want to enable your system kernel to handle system-calls from ELF binaries for 31 bit ESA. This option diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 6302f508258..0fed81d91e0 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -7,6 +7,11 @@ # CFLAGS_smp.o := -Wno-nonnull +# +# Pass UTS_MACHINE for user_regset definition +# +CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' + obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ s390_ext.o debug.o irq.o ipl.o dis.o diag.o @@ -23,7 +28,7 @@ obj-$(CONFIG_AUDIT) += audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ compat_wrapper.o compat_exec_domain.o \ - binfmt_elf32.o $(compat-obj-y) + $(compat-obj-y) obj-$(CONFIG_VIRT_TIMER) += vtime.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c deleted file mode 100644 index 3e1c315b736..00000000000 --- a/arch/s390/kernel/binfmt_elf32.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Support for 32-bit Linux for S390 ELF binaries. - * - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Gerhard Tonn (ton@de.ibm.com) - * - * Heavily inspired by the 32-bit Sparc compat code which is - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) - */ - -#define __ASMS390_ELF_H - -#include - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2MSB -#define ELF_ARCH EM_S390 - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ - && (x)->e_ident[EI_CLASS] == ELF_CLASS) - -/* ELF register definitions */ -#define NUM_GPRS 16 -#define NUM_FPRS 16 -#define NUM_ACRS 16 - -/* For SVR4/S390 the function pointer to be registered with `atexit` is - passed in R14. */ -#define ELF_PLAT_INIT(_r, load_addr) \ - do { \ - _r->gprs[14] = 0; \ - } while(0) - -#define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) - -/* Wow, the "main" arch needs arch dependent functions too.. :) */ - -/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is - now struct_user_regs, they are different) */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) dump_regs32(regs, &pr_reg); - -#define ELF_CORE_COPY_TASK_REGS(tsk, regs) dump_task_regs32(tsk, regs) - -#define ELF_CORE_COPY_FPREGS(tsk, fpregs) dump_task_fpu(tsk, fpregs) - -/* This yields a mask that user programs can use to figure out what - instruction set this CPU supports. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. - - For the moment, we have only optimizations for the Intel generations, - but that could change... */ - -#define ELF_PLATFORM (NULL) - -#define SET_PERSONALITY(ex, ibcs2) \ -do { \ - if (ibcs2) \ - set_personality(PER_SVR4); \ - else if (current->personality != PER_LINUX32) \ - set_personality(PER_LINUX); \ - set_thread_flag(TIF_31BIT); \ -} while (0) - -#include "compat_linux.h" - -typedef _s390_fp_regs32 elf_fpregset_t; - -typedef struct -{ - - _psw_t32 psw; - __u32 gprs[__NUM_GPRS]; - __u32 acrs[__NUM_ACRS]; - __u32 orig_gpr2; -} s390_regs32; -typedef s390_regs32 elf_gregset_t; - -static inline int dump_regs32(struct pt_regs *ptregs, elf_gregset_t *regs) -{ - int i; - - memcpy(®s->psw.mask, &ptregs->psw.mask, 4); - memcpy(®s->psw.addr, (char *)&ptregs->psw.addr + 4, 4); - for (i = 0; i < NUM_GPRS; i++) - regs->gprs[i] = ptregs->gprs[i]; - save_access_regs(regs->acrs); - regs->orig_gpr2 = ptregs->orig_gpr2; - return 1; -} - -static inline int dump_task_regs32(struct task_struct *tsk, elf_gregset_t *regs) -{ - struct pt_regs *ptregs = task_pt_regs(tsk); - int i; - - memcpy(®s->psw.mask, &ptregs->psw.mask, 4); - memcpy(®s->psw.addr, (char *)&ptregs->psw.addr + 4, 4); - for (i = 0; i < NUM_GPRS; i++) - regs->gprs[i] = ptregs->gprs[i]; - memcpy(regs->acrs, tsk->thread.acrs, sizeof(regs->acrs)); - regs->orig_gpr2 = ptregs->orig_gpr2; - return 1; -} - -static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) -{ - if (tsk == current) - save_fp_regs((s390_fp_regs *) fpregs); - else - memcpy(fpregs, &tsk->thread.fp_regs, sizeof(elf_fpregset_t)); - return 1; -} - -#include -#include -#include -#include -#include -#include - -#define elf_prstatus elf_prstatus32 -struct elf_prstatus32 -{ - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - u32 pr_sigpend; /* Set of pending signals */ - u32 pr_sighold; /* Set of held signals */ - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pr_sid; - struct compat_timeval pr_utime; /* User time */ - struct compat_timeval pr_stime; /* System time */ - struct compat_timeval pr_cutime; /* Cumulative user time */ - struct compat_timeval pr_cstime; /* Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define elf_prpsinfo elf_prpsinfo32 -struct elf_prpsinfo32 -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - u32 pr_flag; /* flags */ - u16 pr_uid; - u16 pr_gid; - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -#include - -/* -#define init_elf_binfmt init_elf32_binfmt -*/ - -#undef start_thread -#define start_thread start_thread31 - -static inline void start_thread31(struct pt_regs *regs, unsigned long new_psw, - unsigned long new_stackp) -{ - set_fs(USER_DS); - regs->psw.mask = psw_user32_bits; - regs->psw.addr = new_psw; - regs->gprs[15] = new_stackp; - crst_table_downgrade(current->mm, 1UL << 31); -} - -MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries," - " Copyright 2000 IBM Corporation"); -MODULE_AUTHOR("Gerhard Tonn "); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - -#undef cputime_to_timeval -#define cputime_to_timeval cputime_to_compat_timeval -static inline void -cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) -{ - value->tv_usec = cputime % 1000000; - value->tv_sec = cputime / 1000000; -} - -#include "../../../fs/binfmt_elf.c" - diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h index 419aef913ee..cde81fa64f8 100644 --- a/arch/s390/kernel/compat_ptrace.h +++ b/arch/s390/kernel/compat_ptrace.h @@ -1,7 +1,7 @@ #ifndef _PTRACE32_H #define _PTRACE32_H -#include "compat_linux.h" /* needed for _psw_t32 */ +#include "compat_linux.h" /* needed for psw_compat_t */ typedef struct { __u32 cr[3]; @@ -38,7 +38,7 @@ typedef struct { struct user_regs_struct32 { - _psw_t32 psw; + psw_compat_t psw; u32 gprs[NUM_GPRS]; u32 acrs[NUM_ACRS]; u32 orig_gpr2; diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 35827b9bd4d..2815bfe348a 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -47,6 +49,11 @@ #include "compat_ptrace.h" #endif +enum s390_regset { + REGSET_GENERAL, + REGSET_FP, +}; + static void FixPerRegisters(struct task_struct *task) { @@ -126,24 +133,10 @@ ptrace_disable(struct task_struct *child) * struct user contain pad bytes that should be read as zeroes. * Lovely... */ -static int -peek_user(struct task_struct *child, addr_t addr, addr_t data) +static unsigned long __peek_user(struct task_struct *child, addr_t addr) { struct user *dummy = NULL; - addr_t offset, tmp, mask; - - /* - * Stupid gdb peeks/pokes the access registers in 64 bit with - * an alignment of 4. Programmers from hell... - */ - mask = __ADDR_MASK; -#ifdef CONFIG_64BIT - if (addr >= (addr_t) &dummy->regs.acrs && - addr < (addr_t) &dummy->regs.orig_gpr2) - mask = 3; -#endif - if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) - return -EIO; + addr_t offset, tmp; if (addr < (addr_t) &dummy->regs.acrs) { /* @@ -197,24 +190,18 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) } else tmp = 0; - return put_user(tmp, (addr_t __user *) data); + return tmp; } -/* - * Write a word to the user area of a process at location addr. This - * operation does have an additional problem compared to peek_user. - * Stores to the program status word and on the floating point - * control register needs to get checked for validity. - */ static int -poke_user(struct task_struct *child, addr_t addr, addr_t data) +peek_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset, mask; + addr_t tmp, mask; /* * Stupid gdb peeks/pokes the access registers in 64 bit with - * an alignment of 4. Programmers from hell indeed... + * an alignment of 4. Programmers from hell... */ mask = __ADDR_MASK; #ifdef CONFIG_64BIT @@ -225,6 +212,21 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; + tmp = __peek_user(child, addr); + return put_user(tmp, (addr_t __user *) data); +} + +/* + * Write a word to the user area of a process at location addr. This + * operation does have an additional problem compared to peek_user. + * Stores to the program status word and on the floating point + * control register needs to get checked for validity. + */ +static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) +{ + struct user *dummy = NULL; + addr_t offset; + if (addr < (addr_t) &dummy->regs.acrs) { /* * psw and gprs are stored on the stack @@ -292,6 +294,28 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) return 0; } +static int +poke_user(struct task_struct *child, addr_t addr, addr_t data) +{ + struct user *dummy = NULL; + addr_t mask; + + /* + * Stupid gdb peeks/pokes the access registers in 64 bit with + * an alignment of 4. Programmers from hell indeed... + */ + mask = __ADDR_MASK; +#ifdef CONFIG_64BIT + if (addr >= (addr_t) &dummy->regs.acrs && + addr < (addr_t) &dummy->regs.orig_gpr2) + mask = 3; +#endif + if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) + return -EIO; + + return __poke_user(child, addr, data); +} + long arch_ptrace(struct task_struct *child, long request, long addr, long data) { ptrace_area parea; @@ -367,18 +391,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* * Same as peek_user but for a 31 bit program. */ -static int -peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) +static u32 __peek_user_compat(struct task_struct *child, addr_t addr) { struct user32 *dummy32 = NULL; per_struct32 *dummy_per32 = NULL; addr_t offset; __u32 tmp; - if (!test_thread_flag(TIF_31BIT) || - (addr & 3) || addr > sizeof(struct user) - 3) - return -EIO; - if (addr < (addr_t) &dummy32->regs.acrs) { /* * psw and gprs are stored on the stack @@ -435,25 +454,32 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) } else tmp = 0; + return tmp; +} + +static int peek_user_compat(struct task_struct *child, + addr_t addr, addr_t data) +{ + __u32 tmp; + + if (!test_thread_flag(TIF_31BIT) || + (addr & 3) || addr > sizeof(struct user) - 3) + return -EIO; + + tmp = __peek_user_compat(child, addr); return put_user(tmp, (__u32 __user *) data); } /* * Same as poke_user but for a 31 bit program. */ -static int -poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) +static int __poke_user_compat(struct task_struct *child, + addr_t addr, addr_t data) { struct user32 *dummy32 = NULL; per_struct32 *dummy_per32 = NULL; + __u32 tmp = (__u32) data; addr_t offset; - __u32 tmp; - - if (!test_thread_flag(TIF_31BIT) || - (addr & 3) || addr > sizeof(struct user32) - 3) - return -EIO; - - tmp = (__u32) data; if (addr < (addr_t) &dummy32->regs.acrs) { /* @@ -528,6 +554,16 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) return 0; } +static int poke_user_compat(struct task_struct *child, + addr_t addr, addr_t data) +{ + if (!test_thread_flag(TIF_31BIT) || + (addr & 3) || addr > sizeof(struct user32) - 3) + return -EIO; + + return __poke_user_compat(child, addr, data); +} + long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) { @@ -539,11 +575,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, switch (request) { case PTRACE_PEEKUSR: /* read the word at location addr in the USER area. */ - return peek_user_emu31(child, addr, data); + return peek_user_compat(child, addr, data); case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - return poke_user_emu31(child, addr, data); + return poke_user_compat(child, addr, data); case PTRACE_PEEKUSR_AREA: case PTRACE_POKEUSR_AREA: @@ -555,13 +591,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, copied = 0; while (copied < parea.len) { if (request == PTRACE_PEEKUSR_AREA) - ret = peek_user_emu31(child, addr, data); + ret = peek_user_compat(child, addr, data); else { __u32 utmp; if (get_user(utmp, (__u32 __force __user *) data)) return -EFAULT; - ret = poke_user_emu31(child, addr, utmp); + ret = poke_user_compat(child, addr, utmp); } if (ret) return ret; @@ -610,3 +646,240 @@ syscall_trace(struct pt_regs *regs, int entryexit) regs->gprs[2], regs->orig_gpr2, regs->gprs[3], regs->gprs[4], regs->gprs[5]); } + +/* + * user_regset definitions. + */ + +static int s390_regs_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + if (target == current) + save_access_regs(target->thread.acrs); + + if (kbuf) { + unsigned long *k = kbuf; + while (count > 0) { + *k++ = __peek_user(target, pos); + count -= sizeof(*k); + pos += sizeof(*k); + } + } else { + unsigned long __user *u = ubuf; + while (count > 0) { + if (__put_user(__peek_user(target, pos), u++)) + return -EFAULT; + count -= sizeof(*u); + pos += sizeof(*u); + } + } + return 0; +} + +static int s390_regs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int rc = 0; + + if (target == current) + save_access_regs(target->thread.acrs); + + if (kbuf) { + const unsigned long *k = kbuf; + while (count > 0 && !rc) { + rc = __poke_user(target, pos, *k++); + count -= sizeof(*k); + pos += sizeof(*k); + } + } else { + const unsigned long __user *u = ubuf; + while (count > 0 && !rc) { + unsigned long word; + rc = __get_user(word, u++); + if (rc) + break; + rc = __poke_user(target, pos, word); + count -= sizeof(*u); + pos += sizeof(*u); + } + } + + if (rc == 0 && target == current) + restore_access_regs(target->thread.acrs); + + return rc; +} + +static int s390_fpregs_get(struct task_struct *target, + const struct user_regset *regset, unsigned int pos, + unsigned int count, void *kbuf, void __user *ubuf) +{ + if (target == current) + save_fp_regs(&target->thread.fp_regs); + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.fp_regs, 0, -1); +} + +static int s390_fpregs_set(struct task_struct *target, + const struct user_regset *regset, unsigned int pos, + unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + int rc = 0; + + if (target == current) + save_fp_regs(&target->thread.fp_regs); + + /* If setting FPC, must validate it first. */ + if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) { + u32 fpc[2] = { target->thread.fp_regs.fpc, 0 }; + rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpc, + 0, offsetof(s390_fp_regs, fprs)); + if (rc) + return rc; + if ((fpc[0] & ~FPC_VALID_MASK) != 0 || fpc[1] != 0) + return -EINVAL; + target->thread.fp_regs.fpc = fpc[0]; + } + + if (rc == 0 && count > 0) + rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + target->thread.fp_regs.fprs, + offsetof(s390_fp_regs, fprs), -1); + + if (rc == 0 && target == current) + restore_fp_regs(&target->thread.fp_regs); + + return rc; +} + +static const struct user_regset s390_regsets[] = { + [REGSET_GENERAL] = { + .core_note_type = NT_PRSTATUS, + .n = sizeof(s390_regs) / sizeof(long), + .size = sizeof(long), + .align = sizeof(long), + .get = s390_regs_get, + .set = s390_regs_set, + }, + [REGSET_FP] = { + .core_note_type = NT_PRFPREG, + .n = sizeof(s390_fp_regs) / sizeof(long), + .size = sizeof(long), + .align = sizeof(long), + .get = s390_fpregs_get, + .set = s390_fpregs_set, + }, +}; + +static const struct user_regset_view user_s390_view = { + .name = UTS_MACHINE, + .e_machine = EM_S390, + .regsets = s390_regsets, + .n = ARRAY_SIZE(s390_regsets) +}; + +#ifdef CONFIG_COMPAT +static int s390_compat_regs_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + if (target == current) + save_access_regs(target->thread.acrs); + + if (kbuf) { + compat_ulong_t *k = kbuf; + while (count > 0) { + *k++ = __peek_user_compat(target, pos); + count -= sizeof(*k); + pos += sizeof(*k); + } + } else { + compat_ulong_t __user *u = ubuf; + while (count > 0) { + if (__put_user(__peek_user_compat(target, pos), u++)) + return -EFAULT; + count -= sizeof(*u); + pos += sizeof(*u); + } + } + return 0; +} + +static int s390_compat_regs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int rc = 0; + + if (target == current) + save_access_regs(target->thread.acrs); + + if (kbuf) { + const compat_ulong_t *k = kbuf; + while (count > 0 && !rc) { + rc = __poke_user_compat(target, pos, *k++); + count -= sizeof(*k); + pos += sizeof(*k); + } + } else { + const compat_ulong_t __user *u = ubuf; + while (count > 0 && !rc) { + compat_ulong_t word; + rc = __get_user(word, u++); + if (rc) + break; + rc = __poke_user_compat(target, pos, word); + count -= sizeof(*u); + pos += sizeof(*u); + } + } + + if (rc == 0 && target == current) + restore_access_regs(target->thread.acrs); + + return rc; +} + +static const struct user_regset s390_compat_regsets[] = { + [REGSET_GENERAL] = { + .core_note_type = NT_PRSTATUS, + .n = sizeof(s390_compat_regs) / sizeof(compat_long_t), + .size = sizeof(compat_long_t), + .align = sizeof(compat_long_t), + .get = s390_compat_regs_get, + .set = s390_compat_regs_set, + }, + [REGSET_FP] = { + .core_note_type = NT_PRFPREG, + .n = sizeof(s390_fp_regs) / sizeof(compat_long_t), + .size = sizeof(compat_long_t), + .align = sizeof(compat_long_t), + .get = s390_fpregs_get, + .set = s390_fpregs_set, + }, +}; + +static const struct user_regset_view user_s390_compat_view = { + .name = "s390", + .e_machine = EM_S390, + .regsets = s390_compat_regsets, + .n = ARRAY_SIZE(s390_compat_regsets) +}; +#endif + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ +#ifdef CONFIG_COMPAT + if (test_tsk_thread_flag(task, TIF_31BIT)) + return &user_s390_compat_view; +#endif + return &user_s390_view; +} diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h index b3ac262c458..3cad5692381 100644 --- a/include/asm-s390/elf.h +++ b/include/asm-s390/elf.h @@ -113,6 +113,9 @@ typedef s390_fp_regs elf_fpregset_t; typedef s390_regs elf_gregset_t; +typedef s390_fp_regs compat_elf_fpregset_t; +typedef s390_compat_regs compat_elf_gregset_t; + #include /* for task_struct */ #include /* for save_access_regs */ #include @@ -123,6 +126,10 @@ typedef s390_regs elf_gregset_t; #define elf_check_arch(x) \ (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ && (x)->e_ident[EI_CLASS] == ELF_CLASS) +#define compat_elf_check_arch(x) \ + (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ + && (x)->e_ident[EI_CLASS] == ELF_CLASS) +#define compat_start_thread start_thread31 /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ @@ -131,6 +138,7 @@ typedef s390_regs elf_gregset_t; _r->gprs[14] = 0; \ } while (0) +#define CORE_DUMP_USE_REGSET #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 @@ -140,44 +148,6 @@ typedef s390_regs elf_gregset_t; that it will "exec", and that there is sufficient room for the brk. */ #define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) -/* Wow, the "main" arch needs arch dependent functions too.. :) */ - -/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is - now struct_user_regs, they are different) */ - -static inline int dump_regs(struct pt_regs *ptregs, elf_gregset_t *regs) -{ - memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs)); - save_access_regs(regs->acrs); - regs->orig_gpr2 = ptregs->orig_gpr2; - return 1; -} - -#define ELF_CORE_COPY_REGS(pr_reg, regs) dump_regs(regs, &pr_reg); - -static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) -{ - struct pt_regs *ptregs = task_pt_regs(tsk); - memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs)); - memcpy(regs->acrs, tsk->thread.acrs, sizeof(regs->acrs)); - regs->orig_gpr2 = ptregs->orig_gpr2; - return 1; -} - -#define ELF_CORE_COPY_TASK_REGS(tsk, regs) dump_task_regs(tsk, regs) - -static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) -{ - if (tsk == current) - save_fp_regs(fpregs); - else - memcpy(fpregs, &tsk->thread.fp_regs, sizeof(elf_fpregset_t)); - return 1; -} - -#define ELF_CORE_COPY_FPREGS(tsk, fpregs) dump_task_fpu(tsk, fpregs) - - /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. */ @@ -204,7 +174,10 @@ do { \ set_personality(PER_SVR4); \ else if (current->personality != PER_LINUX32) \ set_personality(PER_LINUX); \ - clear_thread_flag(TIF_31BIT); \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ + set_thread_flag(TIF_31BIT); \ + else \ + clear_thread_flag(TIF_31BIT); \ } while (0) #endif /* __s390x__ */ diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index a00f79dd323..5483c28b8bc 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -143,11 +143,19 @@ struct stack_frame { /* * Do necessary setup to start up a new thread. */ -#define start_thread(regs, new_psw, new_stackp) do { \ +#define start_thread(regs, new_psw, new_stackp) do { \ set_fs(USER_DS); \ regs->psw.mask = psw_user_bits; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ - regs->gprs[15] = new_stackp ; \ + regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->gprs[15] = new_stackp; \ +} while (0) + +#define start_thread31(regs, new_psw, new_stackp) do { \ + set_fs(USER_DS); \ + regs->psw.mask = psw_user32_bits; \ + regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->gprs[15] = new_stackp; \ + crst_table_downgrade(current->mm, 1UL << 31); \ } while (0) /* Forward declaration, a strange C thing */ diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index d7d4e2eb3e6..af2c9ac28a0 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h @@ -215,6 +215,12 @@ typedef struct unsigned long addr; } __attribute__ ((aligned(8))) psw_t; +typedef struct +{ + __u32 mask; + __u32 addr; +} __attribute__ ((aligned(8))) psw_compat_t; + #ifndef __s390x__ #define PSW_MASK_PER 0x40000000UL @@ -292,6 +298,15 @@ typedef struct unsigned long orig_gpr2; } s390_regs; +typedef struct +{ + psw_compat_t psw; + __u32 gprs[NUM_GPRS]; + __u32 acrs[NUM_ACRS]; + __u32 orig_gpr2; +} s390_compat_regs; + + #ifdef __KERNEL__ #include #include -- GitLab From 761cdf6aacdb76f819050f4938cdab1f4cdcb945 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:58:55 +0200 Subject: [PATCH 1762/2509] [S390] initrd vs bss section clearing. In case the initrd is located within the bss section it will be overwritten when the section is cleared. To prevent this just move the initrd right behind the bss section if it starts within the section. The current code already moves the initrd if the bootmem allocator bitmap would overwrite it. With this patch we should be safe against initrd corruptions. Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index d0e09684b9c..b2226e41f06 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -380,6 +380,23 @@ static __init void detect_machine_facilities(void) #endif } +static __init void rescue_initrd(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + /* + * Move the initrd right behind the bss section in case it starts + * within the bss section. So we don't overwrite it when the bss + * section gets cleared. + */ + if (!INITRD_START || !INITRD_SIZE) + return; + if (INITRD_START >= (unsigned long) __bss_stop) + return; + memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE); + INITRD_START = (unsigned long) __bss_stop; +#endif +} + /* * Save ipl parameters, clear bss memory, initialize storage keys * and create a kernel NSS at startup if the SAVESYS= parm is defined @@ -389,6 +406,7 @@ void __init startup_init(void) unsigned long long memsize; ipl_save_parameters(); + rescue_initrd(); clear_bss_section(); init_kernel_storage_key(); lockdep_init(); -- GitLab From d2fec595511b5718bdb65645b3d5d99800d97943 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:58:56 +0200 Subject: [PATCH 1763/2509] [S390] stp support. Add support for clock synchronization with the server time protocol. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/time.c | 634 ++++++++++++++++++++++++++++++---------- drivers/s390/cio/chsc.c | 49 ++++ drivers/s390/s390mach.c | 4 + drivers/s390/s390mach.h | 3 + include/asm-s390/etr.h | 45 ++- 5 files changed, 582 insertions(+), 153 deletions(-) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 7aec676fefd..7418bebb547 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -3,7 +3,7 @@ * Time of day based timer functions. * * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright IBM Corp. 1999, 2008 * Author(s): Hartmut Penner (hp@de.ibm.com), * Martin Schwidefsky (schwidefsky@de.ibm.com), * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -162,7 +163,7 @@ void init_cpu_timer(void) /* Enable clock comparator timer interrupt. */ __ctl_set_bit(0,11); - /* Always allow ETR external interrupts, even without an ETR. */ + /* Always allow the timing alert external interrupt. */ __ctl_set_bit(0, 4); } @@ -170,8 +171,21 @@ static void clock_comparator_interrupt(__u16 code) { } +static void etr_timing_alert(struct etr_irq_parm *); +static void stp_timing_alert(struct stp_irq_parm *); + +static void timing_alert_interrupt(__u16 code) +{ + if (S390_lowcore.ext_params & 0x00c40000) + etr_timing_alert((struct etr_irq_parm *) + &S390_lowcore.ext_params); + if (S390_lowcore.ext_params & 0x00038000) + stp_timing_alert((struct stp_irq_parm *) + &S390_lowcore.ext_params); +} + static void etr_reset(void); -static void etr_ext_handler(__u16); +static void stp_reset(void); /* * Get the TOD clock running. @@ -181,6 +195,7 @@ static u64 __init reset_tod_clock(void) u64 time; etr_reset(); + stp_reset(); if (store_clock(&time) == 0) return time; /* TOD clock not running. Set the clock to Unix Epoch. */ @@ -231,8 +246,9 @@ void __init time_init(void) if (clocksource_register(&clocksource_tod) != 0) panic("Could not register TOD clock source"); - /* request the etr external interrupt */ - if (register_early_external_interrupt(0x1406, etr_ext_handler, + /* request the timing alert external interrupt */ + if (register_early_external_interrupt(0x1406, + timing_alert_interrupt, &ext_int_etr_cc) != 0) panic("Couldn't request external interrupt 0x1406"); @@ -244,11 +260,113 @@ void __init time_init(void) #endif } +/* + * The time is "clock". old is what we think the time is. + * Adjust the value by a multiple of jiffies and add the delta to ntp. + * "delay" is an approximation how long the synchronization took. If + * the time correction is positive, then "delay" is subtracted from + * the time difference and only the remaining part is passed to ntp. + */ +static unsigned long long adjust_time(unsigned long long old, + unsigned long long clock, + unsigned long long delay) +{ + unsigned long long delta, ticks; + struct timex adjust; + + if (clock > old) { + /* It is later than we thought. */ + delta = ticks = clock - old; + delta = ticks = (delta < delay) ? 0 : delta - delay; + delta -= do_div(ticks, CLK_TICKS_PER_JIFFY); + adjust.offset = ticks * (1000000 / HZ); + } else { + /* It is earlier than we thought. */ + delta = ticks = old - clock; + delta -= do_div(ticks, CLK_TICKS_PER_JIFFY); + delta = -delta; + adjust.offset = -ticks * (1000000 / HZ); + } + jiffies_timer_cc += delta; + if (adjust.offset != 0) { + printk(KERN_NOTICE "etr: time adjusted by %li micro-seconds\n", + adjust.offset); + adjust.modes = ADJ_OFFSET_SINGLESHOT; + do_adjtimex(&adjust); + } + return delta; +} + +static DEFINE_PER_CPU(atomic_t, clock_sync_word); +static unsigned long clock_sync_flags; + +#define CLOCK_SYNC_HAS_ETR 0 +#define CLOCK_SYNC_HAS_STP 1 +#define CLOCK_SYNC_ETR 2 +#define CLOCK_SYNC_STP 3 + +/* + * The synchronous get_clock function. It will write the current clock + * value to the clock pointer and return 0 if the clock is in sync with + * the external time source. If the clock mode is local it will return + * -ENOSYS and -EAGAIN if the clock is not in sync with the external + * reference. + */ +int get_sync_clock(unsigned long long *clock) +{ + atomic_t *sw_ptr; + unsigned int sw0, sw1; + + sw_ptr = &get_cpu_var(clock_sync_word); + sw0 = atomic_read(sw_ptr); + *clock = get_clock(); + sw1 = atomic_read(sw_ptr); + put_cpu_var(clock_sync_sync); + if (sw0 == sw1 && (sw0 & 0x80000000U)) + /* Success: time is in sync. */ + return 0; + if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags) && + !test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) + return -ENOSYS; + if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags) && + !test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) + return -EACCES; + return -EAGAIN; +} +EXPORT_SYMBOL(get_sync_clock); + +/* + * Make get_sync_clock return -EAGAIN. + */ +static void disable_sync_clock(void *dummy) +{ + atomic_t *sw_ptr = &__get_cpu_var(clock_sync_word); + /* + * Clear the in-sync bit 2^31. All get_sync_clock calls will + * fail until the sync bit is turned back on. In addition + * increase the "sequence" counter to avoid the race of an + * etr event and the complete recovery against get_sync_clock. + */ + atomic_clear_mask(0x80000000, sw_ptr); + atomic_inc(sw_ptr); +} + +/* + * Make get_sync_clock return 0 again. + * Needs to be called from a context disabled for preemption. + */ +static void enable_sync_clock(void) +{ + atomic_t *sw_ptr = &__get_cpu_var(clock_sync_word); + atomic_set_mask(0x80000000, sw_ptr); +} + /* * External Time Reference (ETR) code. */ static int etr_port0_online; static int etr_port1_online; +static int etr_steai_available; static int __init early_parse_etr(char *p) { @@ -273,12 +391,6 @@ enum etr_event { ETR_EVENT_UPDATE, }; -enum etr_flags { - ETR_FLAG_ENOSYS, - ETR_FLAG_EACCES, - ETR_FLAG_STEAI, -}; - /* * Valid bit combinations of the eacr register are (x = don't care): * e0 e1 dp p0 p1 ea es sl @@ -305,73 +417,17 @@ enum etr_flags { */ static struct etr_eacr etr_eacr; static u64 etr_tolec; /* time of last eacr update */ -static unsigned long etr_flags; static struct etr_aib etr_port0; static int etr_port0_uptodate; static struct etr_aib etr_port1; static int etr_port1_uptodate; static unsigned long etr_events; static struct timer_list etr_timer; -static DEFINE_PER_CPU(atomic_t, etr_sync_word); static void etr_timeout(unsigned long dummy); static void etr_work_fn(struct work_struct *work); static DECLARE_WORK(etr_work, etr_work_fn); -/* - * The etr get_clock function. It will write the current clock value - * to the clock pointer and return 0 if the clock is in sync with the - * external time source. If the clock mode is local it will return - * -ENOSYS and -EAGAIN if the clock is not in sync with the external - * reference. This function is what ETR is all about.. - */ -int get_sync_clock(unsigned long long *clock) -{ - atomic_t *sw_ptr; - unsigned int sw0, sw1; - - sw_ptr = &get_cpu_var(etr_sync_word); - sw0 = atomic_read(sw_ptr); - *clock = get_clock(); - sw1 = atomic_read(sw_ptr); - put_cpu_var(etr_sync_sync); - if (sw0 == sw1 && (sw0 & 0x80000000U)) - /* Success: time is in sync. */ - return 0; - if (test_bit(ETR_FLAG_ENOSYS, &etr_flags)) - return -ENOSYS; - if (test_bit(ETR_FLAG_EACCES, &etr_flags)) - return -EACCES; - return -EAGAIN; -} -EXPORT_SYMBOL(get_sync_clock); - -/* - * Make get_sync_clock return -EAGAIN. - */ -static void etr_disable_sync_clock(void *dummy) -{ - atomic_t *sw_ptr = &__get_cpu_var(etr_sync_word); - /* - * Clear the in-sync bit 2^31. All get_sync_clock calls will - * fail until the sync bit is turned back on. In addition - * increase the "sequence" counter to avoid the race of an - * etr event and the complete recovery against get_sync_clock. - */ - atomic_clear_mask(0x80000000, sw_ptr); - atomic_inc(sw_ptr); -} - -/* - * Make get_sync_clock return 0 again. - * Needs to be called from a context disabled for preemption. - */ -static void etr_enable_sync_clock(void) -{ - atomic_t *sw_ptr = &__get_cpu_var(etr_sync_word); - atomic_set_mask(0x80000000, sw_ptr); -} - /* * Reset ETR attachment. */ @@ -381,15 +437,13 @@ static void etr_reset(void) .e0 = 0, .e1 = 0, ._pad0 = 4, .dp = 0, .p0 = 0, .p1 = 0, ._pad1 = 0, .ea = 0, .es = 0, .sl = 0 }; - if (etr_setr(&etr_eacr) == 0) + if (etr_setr(&etr_eacr) == 0) { etr_tolec = get_clock(); - else { - set_bit(ETR_FLAG_ENOSYS, &etr_flags); - if (etr_port0_online || etr_port1_online) { - printk(KERN_WARNING "Running on non ETR capable " - "machine, only local mode available.\n"); - etr_port0_online = etr_port1_online = 0; - } + set_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags); + } else if (etr_port0_online || etr_port1_online) { + printk(KERN_WARNING "Running on non ETR capable " + "machine, only local mode available.\n"); + etr_port0_online = etr_port1_online = 0; } } @@ -397,14 +451,12 @@ static int __init etr_init(void) { struct etr_aib aib; - if (test_bit(ETR_FLAG_ENOSYS, &etr_flags)) + if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags)) return 0; /* Check if this machine has the steai instruction. */ if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0) - set_bit(ETR_FLAG_STEAI, &etr_flags); + etr_steai_available = 1; setup_timer(&etr_timer, etr_timeout, 0UL); - if (!etr_port0_online && !etr_port1_online) - set_bit(ETR_FLAG_EACCES, &etr_flags); if (etr_port0_online) { set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); schedule_work(&etr_work); @@ -435,7 +487,8 @@ void etr_switch_to_local(void) { if (!etr_eacr.sl) return; - etr_disable_sync_clock(NULL); + if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) + disable_sync_clock(NULL); set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events); schedule_work(&etr_work); } @@ -450,23 +503,21 @@ void etr_sync_check(void) { if (!etr_eacr.es) return; - etr_disable_sync_clock(NULL); + if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) + disable_sync_clock(NULL); set_bit(ETR_EVENT_SYNC_CHECK, &etr_events); schedule_work(&etr_work); } /* - * ETR external interrupt. There are two causes: + * ETR timing alert. There are two causes: * 1) port state change, check the usability of the port * 2) port alert, one of the ETR-data-validity bits (v1-v2 bits of the * sldr-status word) or ETR-data word 1 (edf1) or ETR-data word 3 (edf3) * or ETR-data word 4 (edf4) has changed. */ -static void etr_ext_handler(__u16 code) +static void etr_timing_alert(struct etr_irq_parm *intparm) { - struct etr_interruption_parameter *intparm = - (struct etr_interruption_parameter *) &S390_lowcore.ext_params; - if (intparm->pc0) /* ETR port 0 state change. */ set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); @@ -591,58 +642,23 @@ static int etr_aib_follows(struct etr_aib *a1, struct etr_aib *a2, int p) return 1; } -/* - * The time is "clock". old is what we think the time is. - * Adjust the value by a multiple of jiffies and add the delta to ntp. - * "delay" is an approximation how long the synchronization took. If - * the time correction is positive, then "delay" is subtracted from - * the time difference and only the remaining part is passed to ntp. - */ -static unsigned long long etr_adjust_time(unsigned long long old, - unsigned long long clock, - unsigned long long delay) -{ - unsigned long long delta, ticks; - struct timex adjust; - - if (clock > old) { - /* It is later than we thought. */ - delta = ticks = clock - old; - delta = ticks = (delta < delay) ? 0 : delta - delay; - delta -= do_div(ticks, CLK_TICKS_PER_JIFFY); - adjust.offset = ticks * (1000000 / HZ); - } else { - /* It is earlier than we thought. */ - delta = ticks = old - clock; - delta -= do_div(ticks, CLK_TICKS_PER_JIFFY); - delta = -delta; - adjust.offset = -ticks * (1000000 / HZ); - } - jiffies_timer_cc += delta; - if (adjust.offset != 0) { - printk(KERN_NOTICE "etr: time adjusted by %li micro-seconds\n", - adjust.offset); - adjust.modes = ADJ_OFFSET_SINGLESHOT; - do_adjtimex(&adjust); - } - return delta; -} - -static struct { +struct clock_sync_data { int in_sync; unsigned long long fixup_cc; -} etr_sync; +}; -static void etr_sync_cpu_start(void *dummy) +static void clock_sync_cpu_start(void *dummy) { - etr_enable_sync_clock(); + struct clock_sync_data *sync = dummy; + + enable_sync_clock(); /* * This looks like a busy wait loop but it isn't. etr_sync_cpus * is called on all other cpus while the TOD clocks is stopped. * __udelay will stop the cpu on an enabled wait psw until the * TOD is running again. */ - while (etr_sync.in_sync == 0) { + while (sync->in_sync == 0) { __udelay(1); /* * A different cpu changes *in_sync. Therefore use @@ -650,17 +666,17 @@ static void etr_sync_cpu_start(void *dummy) */ barrier(); } - if (etr_sync.in_sync != 1) + if (sync->in_sync != 1) /* Didn't work. Clear per-cpu in sync bit again. */ - etr_disable_sync_clock(NULL); + disable_sync_clock(NULL); /* * This round of TOD syncing is done. Set the clock comparator * to the next tick and let the processor continue. */ - fixup_clock_comparator(etr_sync.fixup_cc); + fixup_clock_comparator(sync->fixup_cc); } -static void etr_sync_cpu_end(void *dummy) +static void clock_sync_cpu_end(void *dummy) { } @@ -672,6 +688,7 @@ static void etr_sync_cpu_end(void *dummy) static int etr_sync_clock(struct etr_aib *aib, int port) { struct etr_aib *sync_port; + struct clock_sync_data etr_sync; unsigned long long clock, old_clock, delay, delta; int follows; int rc; @@ -690,9 +707,9 @@ static int etr_sync_clock(struct etr_aib *aib, int port) */ memset(&etr_sync, 0, sizeof(etr_sync)); preempt_disable(); - smp_call_function(etr_sync_cpu_start, NULL, 0, 0); + smp_call_function(clock_sync_cpu_start, &etr_sync, 0, 0); local_irq_disable(); - etr_enable_sync_clock(); + enable_sync_clock(); /* Set clock to next OTE. */ __ctl_set_bit(14, 21); @@ -707,13 +724,13 @@ static int etr_sync_clock(struct etr_aib *aib, int port) /* Adjust Linux timing variables. */ delay = (unsigned long long) (aib->edf2.etv - sync_port->edf2.etv) << 32; - delta = etr_adjust_time(old_clock, clock, delay); + delta = adjust_time(old_clock, clock, delay); etr_sync.fixup_cc = delta; fixup_clock_comparator(delta); /* Verify that the clock is properly set. */ if (!etr_aib_follows(sync_port, aib, port)) { /* Didn't work. */ - etr_disable_sync_clock(NULL); + disable_sync_clock(NULL); etr_sync.in_sync = -EAGAIN; rc = -EAGAIN; } else { @@ -724,12 +741,12 @@ static int etr_sync_clock(struct etr_aib *aib, int port) /* Could not set the clock ?!? */ __ctl_clear_bit(0, 29); __ctl_clear_bit(14, 21); - etr_disable_sync_clock(NULL); + disable_sync_clock(NULL); etr_sync.in_sync = -EAGAIN; rc = -EAGAIN; } local_irq_enable(); - smp_call_function(etr_sync_cpu_end,NULL,0,0); + smp_call_function(clock_sync_cpu_end, NULL, 0, 0); preempt_enable(); return rc; } @@ -832,7 +849,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib, * Do not try to get the alternate port aib if the clock * is not in sync yet. */ - if (!eacr.es) + if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags) && !eacr.es) return eacr; /* @@ -840,7 +857,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib, * the other port immediately. If only stetr is available the * data-port bit toggle has to be used. */ - if (test_bit(ETR_FLAG_STEAI, &etr_flags)) { + if (etr_steai_available) { if (eacr.p0 && !etr_port0_uptodate) { etr_steai_cv(&etr_port0, ETR_STEAI_PORT_0); etr_port0_uptodate = 1; @@ -909,10 +926,10 @@ static void etr_work_fn(struct work_struct *work) if (!eacr.ea) { /* Both ports offline. Reset everything. */ eacr.dp = eacr.es = eacr.sl = 0; - on_each_cpu(etr_disable_sync_clock, NULL, 0, 1); + on_each_cpu(disable_sync_clock, NULL, 0, 1); del_timer_sync(&etr_timer); etr_update_eacr(eacr); - set_bit(ETR_FLAG_EACCES, &etr_flags); + clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags); return; } @@ -953,7 +970,6 @@ static void etr_work_fn(struct work_struct *work) eacr.e1 = 1; sync_port = (etr_port0_uptodate && etr_port_valid(&etr_port0, 0)) ? 0 : -1; - clear_bit(ETR_FLAG_EACCES, &etr_flags); } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_pps_mode) { eacr.sl = 0; eacr.e0 = 0; @@ -962,7 +978,6 @@ static void etr_work_fn(struct work_struct *work) eacr.es = 0; sync_port = (etr_port1_uptodate && etr_port_valid(&etr_port1, 1)) ? 1 : -1; - clear_bit(ETR_FLAG_EACCES, &etr_flags); } else if (eacr.p0 && aib.esw.psc0 == etr_lpsc_operational_step) { eacr.sl = 1; eacr.e0 = 1; @@ -976,7 +991,6 @@ static void etr_work_fn(struct work_struct *work) eacr.e1 = 1; sync_port = (etr_port0_uptodate && etr_port_valid(&etr_port0, 0)) ? 0 : -1; - clear_bit(ETR_FLAG_EACCES, &etr_flags); } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_operational_step) { eacr.sl = 1; eacr.e0 = 0; @@ -985,19 +999,22 @@ static void etr_work_fn(struct work_struct *work) eacr.es = 0; sync_port = (etr_port1_uptodate && etr_port_valid(&etr_port1, 1)) ? 1 : -1; - clear_bit(ETR_FLAG_EACCES, &etr_flags); } else { /* Both ports not usable. */ eacr.es = eacr.sl = 0; sync_port = -1; - set_bit(ETR_FLAG_EACCES, &etr_flags); + clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags); } + if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) + eacr.es = 0; + /* * If the clock is in sync just update the eacr and return. * If there is no valid sync port wait for a port update. */ - if (eacr.es || sync_port < 0) { + if (test_bit(CLOCK_SYNC_STP, &clock_sync_flags) || + eacr.es || sync_port < 0) { etr_update_eacr(eacr); etr_set_tolec_timeout(now); return; @@ -1018,11 +1035,13 @@ static void etr_work_fn(struct work_struct *work) * and set up a timer to try again after 0.5 seconds */ etr_update_eacr(eacr); + set_bit(CLOCK_SYNC_ETR, &clock_sync_flags); if (now < etr_tolec + (1600000 << 12) || etr_sync_clock(&aib, sync_port) != 0) { /* Sync failed. Try again in 1/2 second. */ eacr.es = 0; etr_update_eacr(eacr); + clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags); etr_set_sync_timeout(); } else etr_set_tolec_timeout(now); @@ -1097,8 +1116,8 @@ static ssize_t etr_online_store(struct sys_device *dev, value = simple_strtoul(buf, NULL, 0); if (value != 0 && value != 1) return -EINVAL; - if (test_bit(ETR_FLAG_ENOSYS, &etr_flags)) - return -ENOSYS; + if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags)) + return -EOPNOTSUPP; if (dev == &etr_port0_dev) { if (etr_port0_online == value) return count; /* Nothing to do. */ @@ -1292,3 +1311,318 @@ out: } device_initcall(etr_init_sysfs); + +/* + * Server Time Protocol (STP) code. + */ +static int stp_online; +static struct stp_sstpi stp_info; +static void *stp_page; + +static void stp_work_fn(struct work_struct *work); +static DECLARE_WORK(stp_work, stp_work_fn); + +static int __init early_parse_stp(char *p) +{ + if (strncmp(p, "off", 3) == 0) + stp_online = 0; + else if (strncmp(p, "on", 2) == 0) + stp_online = 1; + return 0; +} +early_param("stp", early_parse_stp); + +/* + * Reset STP attachment. + */ +static void stp_reset(void) +{ + int rc; + + stp_page = alloc_bootmem_pages(PAGE_SIZE); + rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); + if (rc == 1) + set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags); + else if (stp_online) { + printk(KERN_WARNING "Running on non STP capable machine.\n"); + free_bootmem((unsigned long) stp_page, PAGE_SIZE); + stp_page = NULL; + stp_online = 0; + } +} + +static int __init stp_init(void) +{ + if (test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags) && stp_online) + schedule_work(&stp_work); + return 0; +} + +arch_initcall(stp_init); + +/* + * STP timing alert. There are three causes: + * 1) timing status change + * 2) link availability change + * 3) time control parameter change + * In all three cases we are only interested in the clock source state. + * If a STP clock source is now available use it. + */ +static void stp_timing_alert(struct stp_irq_parm *intparm) +{ + if (intparm->tsc || intparm->lac || intparm->tcpc) + schedule_work(&stp_work); +} + +/* + * STP sync check machine check. This is called when the timing state + * changes from the synchronized state to the unsynchronized state. + * After a STP sync check the clock is not in sync. The machine check + * is broadcasted to all cpus at the same time. + */ +void stp_sync_check(void) +{ + if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) + return; + disable_sync_clock(NULL); + schedule_work(&stp_work); +} + +/* + * STP island condition machine check. This is called when an attached + * server attempts to communicate over an STP link and the servers + * have matching CTN ids and have a valid stratum-1 configuration + * but the configurations do not match. + */ +void stp_island_check(void) +{ + if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) + return; + disable_sync_clock(NULL); + schedule_work(&stp_work); +} + +/* + * STP tasklet. Check for the STP state and take over the clock + * synchronization if the STP clock source is usable. + */ +static void stp_work_fn(struct work_struct *work) +{ + struct clock_sync_data stp_sync; + unsigned long long old_clock, delta; + int rc; + + if (!stp_online) { + chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); + return; + } + + rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0); + if (rc) + return; + + rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + if (rc || stp_info.c == 0) + return; + + /* + * Catch all other cpus and make them wait until we have + * successfully synced the clock. smp_call_function will + * return after all other cpus are in clock_sync_cpu_start. + */ + memset(&stp_sync, 0, sizeof(stp_sync)); + preempt_disable(); + smp_call_function(clock_sync_cpu_start, &stp_sync, 0, 0); + local_irq_disable(); + enable_sync_clock(); + + set_bit(CLOCK_SYNC_STP, &clock_sync_flags); + if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) + schedule_work(&etr_work); + + rc = 0; + if (stp_info.todoff[0] || stp_info.todoff[1] || + stp_info.todoff[2] || stp_info.todoff[3] || + stp_info.tmd != 2) { + old_clock = get_clock(); + rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0); + if (rc == 0) { + delta = adjust_time(old_clock, get_clock(), 0); + fixup_clock_comparator(delta); + rc = chsc_sstpi(stp_page, &stp_info, + sizeof(struct stp_sstpi)); + if (rc == 0 && stp_info.tmd != 2) + rc = -EAGAIN; + } + } + if (rc) { + disable_sync_clock(NULL); + stp_sync.in_sync = -EAGAIN; + clear_bit(CLOCK_SYNC_STP, &clock_sync_flags); + if (etr_port0_online || etr_port1_online) + schedule_work(&etr_work); + } else + stp_sync.in_sync = 1; + + local_irq_enable(); + smp_call_function(clock_sync_cpu_end, NULL, 0, 0); + preempt_enable(); +} + +/* + * STP class sysfs interface functions + */ +static struct sysdev_class stp_sysclass = { + .name = "stp", +}; + +static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online) + return -ENODATA; + return sprintf(buf, "%016llx\n", + *(unsigned long long *) stp_info.ctnid); +} + +static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); + +static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online) + return -ENODATA; + return sprintf(buf, "%i\n", stp_info.ctn); +} + +static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); + +static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online || !(stp_info.vbits & 0x2000)) + return -ENODATA; + return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); +} + +static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); + +static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online || !(stp_info.vbits & 0x8000)) + return -ENODATA; + return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); +} + +static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); + +static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online) + return -ENODATA; + return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); +} + +static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); + +static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online || !(stp_info.vbits & 0x0800)) + return -ENODATA; + return sprintf(buf, "%i\n", (int) stp_info.tto); +} + +static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); + +static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online || !(stp_info.vbits & 0x4000)) + return -ENODATA; + return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); +} + +static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, + stp_time_zone_offset_show, NULL); + +static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online) + return -ENODATA; + return sprintf(buf, "%i\n", stp_info.tmd); +} + +static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); + +static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf) +{ + if (!stp_online) + return -ENODATA; + return sprintf(buf, "%i\n", stp_info.tst); +} + +static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); + +static ssize_t stp_online_show(struct sysdev_class *class, char *buf) +{ + return sprintf(buf, "%i\n", stp_online); +} + +static ssize_t stp_online_store(struct sysdev_class *class, + const char *buf, size_t count) +{ + unsigned int value; + + value = simple_strtoul(buf, NULL, 0); + if (value != 0 && value != 1) + return -EINVAL; + if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) + return -EOPNOTSUPP; + stp_online = value; + schedule_work(&stp_work); + return count; +} + +/* + * Can't use SYSDEV_CLASS_ATTR because the attribute should be named + * stp/online but attr_online already exists in this file .. + */ +static struct sysdev_class_attribute attr_stp_online = { + .attr = { .name = "online", .mode = 0600 }, + .show = stp_online_show, + .store = stp_online_store, +}; + +static struct sysdev_class_attribute *stp_attributes[] = { + &attr_ctn_id, + &attr_ctn_type, + &attr_dst_offset, + &attr_leap_seconds, + &attr_stp_online, + &attr_stratum, + &attr_time_offset, + &attr_time_zone_offset, + &attr_timing_mode, + &attr_timing_state, + NULL +}; + +static int __init stp_init_sysfs(void) +{ + struct sysdev_class_attribute **attr; + int rc; + + rc = sysdev_class_register(&stp_sysclass); + if (rc) + goto out; + for (attr = stp_attributes; *attr; attr++) { + rc = sysdev_class_create_file(&stp_sysclass, *attr); + if (rc) + goto out_unreg; + } + return 0; +out_unreg: + for (; attr >= stp_attributes; attr--) + sysdev_class_remove_file(&stp_sysclass, *attr); + sysdev_class_unregister(&stp_sysclass); +out: + return rc; +} + +device_initcall(stp_init_sysfs); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index cb36f792978..62b0b16fe3d 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -874,3 +874,52 @@ exit: EXPORT_SYMBOL_GPL(css_general_characteristics); EXPORT_SYMBOL_GPL(css_chsc_characteristics); + +int chsc_sstpc(void *page, unsigned int op, u16 ctrl) +{ + struct { + struct chsc_header request; + unsigned int rsvd0; + unsigned int op : 8; + unsigned int rsvd1 : 8; + unsigned int ctrl : 16; + unsigned int rsvd2[5]; + struct chsc_header response; + unsigned int rsvd3[7]; + } __attribute__ ((packed)) *rr; + int rc; + + memset(page, 0, PAGE_SIZE); + rr = page; + rr->request.length = 0x0020; + rr->request.code = 0x0033; + rr->op = op; + rr->ctrl = ctrl; + rc = chsc(rr); + if (rc) + return -EIO; + rc = (rr->response.code == 0x0001) ? 0 : -EIO; + return rc; +} + +int chsc_sstpi(void *page, void *result, size_t size) +{ + struct { + struct chsc_header request; + unsigned int rsvd0[3]; + struct chsc_header response; + char data[size]; + } __attribute__ ((packed)) *rr; + int rc; + + memset(page, 0, PAGE_SIZE); + rr = page; + rr->request.length = 0x0010; + rr->request.code = 0x0038; + rc = chsc(rr); + if (rc) + return -EIO; + memcpy(result, &rr->data, size); + return (rr->response.code == 0x0001) ? 0 : -EIO; +} + diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index fe75152a508..834e9ee7e93 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -458,6 +458,10 @@ s390_do_machine_check(struct pt_regs *regs) etr_sync_check(); if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH)) etr_switch_to_local(); + if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC)) + stp_sync_check(); + if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND)) + stp_island_check(); } if (mci->se) diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h index f11e574076d..d39f8b697d2 100644 --- a/drivers/s390/s390mach.h +++ b/drivers/s390/s390mach.h @@ -112,6 +112,9 @@ static inline int stcrw(struct crw *pcrw ) #define ED_ETR_SYNC 12 /* External damage ETR sync check */ #define ED_ETR_SWITCH 13 /* External damage ETR switch to local */ +#define ED_STP_SYNC 7 /* External damage STP sync check */ +#define ED_STP_ISLAND 6 /* External damage STP island check */ + struct pt_regs; void s390_handle_mcck(void); diff --git a/include/asm-s390/etr.h b/include/asm-s390/etr.h index b498f19bb9a..80ef58c6197 100644 --- a/include/asm-s390/etr.h +++ b/include/asm-s390/etr.h @@ -122,7 +122,7 @@ struct etr_aib { } __attribute__ ((packed,aligned(8))); /* ETR interruption parameter */ -struct etr_interruption_parameter { +struct etr_irq_parm { unsigned int _pad0 : 8; unsigned int pc0 : 1; /* port 0 state change */ unsigned int pc1 : 1; /* port 1 state change */ @@ -213,7 +213,46 @@ static inline int etr_ptff(void *ptff_block, unsigned int func) #define ETR_PTFF_SGS 0x43 /* set gross steering rate */ /* Functions needed by the machine check handler */ -extern void etr_switch_to_local(void); -extern void etr_sync_check(void); +void etr_switch_to_local(void); +void etr_sync_check(void); + +/* STP interruption parameter */ +struct stp_irq_parm { + unsigned int _pad0 : 14; + unsigned int tsc : 1; /* Timing status change */ + unsigned int lac : 1; /* Link availability change */ + unsigned int tcpc : 1; /* Time control parameter change */ + unsigned int _pad2 : 15; +} __attribute__ ((packed)); + +#define STP_OP_SYNC 1 +#define STP_OP_CTRL 3 + +struct stp_sstpi { + unsigned int rsvd0; + unsigned int rsvd1 : 8; + unsigned int stratum : 8; + unsigned int vbits : 16; + unsigned int leaps : 16; + unsigned int tmd : 4; + unsigned int ctn : 4; + unsigned int rsvd2 : 3; + unsigned int c : 1; + unsigned int tst : 4; + unsigned int tzo : 16; + unsigned int dsto : 16; + unsigned int ctrl : 16; + unsigned int rsvd3 : 16; + unsigned int tto; + unsigned int rsvd4; + unsigned int ctnid[3]; + unsigned int rsvd5; + unsigned int todoff[4]; + unsigned int rsvd6[48]; +} __attribute__ ((packed)); + +/* Functions needed by the machine check handler */ +void stp_sync_check(void); +void stp_island_check(void); #endif /* __S390_ETR_H */ -- GitLab From 75784c00876c88ca6e955c39cbb5d47cf408fd3c Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:57 +0200 Subject: [PATCH 1764/2509] [S390] cio: Get rid of css_characteristics_avail. Checking for the validity of the css_*_characteristics is superfluous since they stay 0 for non-successful scsc. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 3 +-- drivers/s390/cio/chsc.h | 1 - drivers/s390/cio/cmf.c | 3 +-- drivers/s390/cio/css.c | 12 +++--------- drivers/s390/cio/qdio.c | 3 --- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 0b3c3109f22..62df43b2124 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -415,8 +415,7 @@ int chp_new(struct chp_id chpid) goto out_free; } /* Get channel-measurement characteristics. */ - if (css_characteristics_avail && css_chsc_characteristics.scmc - && css_chsc_characteristics.secm) { + if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) { ret = chsc_get_channel_measurement_chars(chp); if (ret) goto out_free; diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index d4498d4005d..2a38b509022 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -78,7 +78,6 @@ struct chsc_ssd_info { extern int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd); extern int chsc_determine_css_characteristics(void); -extern int css_characteristics_avail; extern int chsc_alloc_sei_area(void); extern void chsc_free_sei_area(void); diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 6c77c2326bd..77523131a05 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -1344,8 +1344,7 @@ static int __init init_cmf(void) * to basic mode. */ if (format == CMF_AUTODETECT) { - if (!css_characteristics_avail || - !css_general_characteristics.ext_mb) { + if (!css_general_characteristics.ext_mb) { format = CMF_BASIC; } else { format = CMF_EXTENDED; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 062716cf0f0..ebed2212778 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -30,8 +30,6 @@ static int max_ssid = 0; struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; -int css_characteristics_avail = 0; - int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) { @@ -611,7 +609,7 @@ __init_channel_subsystem(struct subchannel_id schid, void *data) static void __init css_generate_pgid(struct channel_subsystem *css, u32 tod_high) { - if (css_characteristics_avail && css_general_characteristics.mcss) { + if (css_general_characteristics.mcss) { css->global_pgid.pgid_high.ext_cssid.version = 0x80; css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid; } else { @@ -748,8 +746,6 @@ init_channel_subsystem (void) ret = chsc_determine_css_characteristics(); if (ret == -ENOMEM) goto out; /* No need to continue. */ - if (ret == 0) - css_characteristics_avail = 1; ret = chsc_alloc_sei_area(); if (ret) @@ -793,8 +789,7 @@ init_channel_subsystem (void) ret = device_register(&css->device); if (ret) goto out_free_all; - if (css_characteristics_avail && - css_chsc_characteristics.secm) { + if (css_chsc_characteristics.secm) { ret = device_create_file(&css->device, &dev_attr_cm_enable); if (ret) @@ -832,7 +827,7 @@ out_unregister: i--; css = channel_subsystems[i]; device_unregister(&css->pseudo_subchannel->dev); - if (css_characteristics_avail && css_chsc_characteristics.secm) + if (css_chsc_characteristics.secm) device_remove_file(&css->device, &dev_attr_cm_enable); device_unregister(&css->device); @@ -956,4 +951,3 @@ subsys_initcall(init_channel_subsystem); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(css_bus_type); -EXPORT_SYMBOL_GPL(css_characteristics_avail); diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 72508d8f3c4..f9be265e7e8 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -2354,9 +2354,6 @@ tiqdio_check_chsc_availability(void) { char dbf_text[15]; - if (!css_characteristics_avail) - return -EIO; - /* Check for bit 41. */ if (!css_general_characteristics.aif) { QDIO_PRINT_WARN("Adapter interruption facility not " \ -- GitLab From 3a3fc29a6d0626fb4897b7391c4e956efbacd394 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:58 +0200 Subject: [PATCH 1765/2509] [S390] cio: Introduce abstract isc definitions. Replace the numeric values for I/O interruption subclass usage with abstract definitions and collect them all in asm/isc.h. This gives us a better overview of which iscs are actually used and makes it possible to better spread out isc usage in the future. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/cio.c | 13 +++++++------ drivers/s390/cio/css.c | 4 +++- drivers/s390/cio/device.c | 3 ++- drivers/s390/cio/qdio.h | 3 ++- include/asm-s390/isc.h | 18 ++++++++++++++++++ 5 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 include/asm-s390/isc.h diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index c24dfcd858d..a4f9130910d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include "cio.h" @@ -699,9 +700,9 @@ void wait_cons_dev(void) if (!console_subchannel_in_use) return; - /* disable all but isc 1 (console device) */ + /* disable all but the console isc */ __ctl_store (save_cr6, 6, 6); - cr6 = 0x40000000; + cr6 = 1UL << (31 - CONSOLE_ISC); __ctl_load (cr6, 6, 6); do { @@ -783,10 +784,10 @@ cio_probe_console(void) } /* - * enable console I/O-interrupt subclass 1 + * enable console I/O-interrupt subclass */ - ctl_set_bit(6, 30); - console_subchannel.schib.pmcw.isc = 1; + ctl_set_bit(6, 31 - CONSOLE_ISC); + console_subchannel.schib.pmcw.isc = CONSOLE_ISC; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; ret = cio_modify(&console_subchannel); @@ -802,7 +803,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm = 0; cio_modify(&console_subchannel); - ctl_clear_bit(6, 30); + ctl_clear_bit(6, 31 - CONSOLE_ISC); console_subchannel_in_use = 0; } diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index ebed2212778..b24618b5362 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "../s390mach.h" #include "css.h" @@ -804,7 +805,8 @@ init_channel_subsystem (void) goto out_pseudo; css_init_done = 1; - ctl_set_bit(6, 28); + /* Enable default isc for I/O subchannels. */ + ctl_set_bit(6, 31 - IO_SCH_ISC); for_each_subchannel(__init_channel_subsystem, NULL); return 0; diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 215d27dba9e..67e7a312395 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -22,6 +22,7 @@ #include #include /* HZ */ #include +#include #include "chp.h" #include "cio.h" @@ -1121,7 +1122,7 @@ static void io_subchannel_init_fields(struct subchannel *sch) else sch->opm = chp_get_sch_opm(sch); sch->lpm = sch->schib.pmcw.pam & sch->opm; - sch->isc = cio_is_console(sch->schid) ? 1 : 3; + sch->isc = cio_is_console(sch->schid) ? CONSOLE_ISC : IO_SCH_ISC; CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X" " - PIM = %02X, PAM = %02X, POM = %02X\n", diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index c3df6b2c38b..733934a166b 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -2,6 +2,7 @@ #define _CIO_QDIO_H #include +#include #include "schid.h" @@ -26,7 +27,7 @@ */ #define IQDIO_FILL_LEVEL_TO_POLL 4 -#define TIQDIO_THININT_ISC 3 +#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 */ diff --git a/include/asm-s390/isc.h b/include/asm-s390/isc.h new file mode 100644 index 00000000000..533a1372234 --- /dev/null +++ b/include/asm-s390/isc.h @@ -0,0 +1,18 @@ +#ifndef _ASM_S390_ISC_H +#define _ASM_S390_ISC_H + +/* + * I/O interruption subclasses used by drivers. + * Please add all used iscs here so that it is possible to distribute + * isc usage between drivers. + * Reminder: 0 is highest priority, 7 lowest. + */ +#define MAX_ISC 7 + +/* Regular I/O interrupts. */ +#define IO_SCH_ISC 3 /* regular I/O subchannels */ +#define CONSOLE_ISC 1 /* console I/O subchannel */ +/* Adapter interrupts. */ +#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ + +#endif /* _ASM_S390_ISC_H */ -- GitLab From da7c5af82879828409f6b81431ac2f9f353ab04e Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:58:59 +0200 Subject: [PATCH 1766/2509] [S390] cio: Allow adapter interrupt handlers per isc. Enhance the adapter interruption API so that device drivers can register a handler for a specific interruption subclass. This will allow different device drivers to move to differently prioritized subclasses in order to avoid congestion. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/airq.c | 45 +++++++++++++++++++++++------------------ drivers/s390/cio/cio.c | 2 +- drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/qdio.c | 6 ++++-- include/asm-s390/airq.h | 4 ++-- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index b7a07a86629..fe6cea15bba 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c @@ -15,6 +15,7 @@ #include #include +#include #include "cio.h" #include "cio_debug.h" @@ -33,15 +34,15 @@ struct airq_t { void *drv_data; }; -static union indicator_t indicators; -static struct airq_t *airqs[NR_AIRQS]; +static union indicator_t indicators[MAX_ISC]; +static struct airq_t *airqs[MAX_ISC][NR_AIRQS]; -static int register_airq(struct airq_t *airq) +static int register_airq(struct airq_t *airq, u8 isc) { int i; for (i = 0; i < NR_AIRQS; i++) - if (!cmpxchg(&airqs[i], NULL, airq)) + if (!cmpxchg(&airqs[isc][i], NULL, airq)) return i; return -ENOMEM; } @@ -50,18 +51,21 @@ static int register_airq(struct airq_t *airq) * s390_register_adapter_interrupt() - register adapter interrupt handler * @handler: adapter handler to be registered * @drv_data: driver data passed with each call to the handler + * @isc: isc for which the handler should be called * * Returns: * Pointer to the indicator to be used on success * ERR_PTR() if registration failed */ void *s390_register_adapter_interrupt(adapter_int_handler_t handler, - void *drv_data) + void *drv_data, u8 isc) { struct airq_t *airq; char dbf_txt[16]; int ret; + if (isc > MAX_ISC) + return ERR_PTR(-EINVAL); airq = kmalloc(sizeof(struct airq_t), GFP_KERNEL); if (!airq) { ret = -ENOMEM; @@ -69,34 +73,35 @@ void *s390_register_adapter_interrupt(adapter_int_handler_t handler, } airq->handler = handler; airq->drv_data = drv_data; - ret = register_airq(airq); - if (ret < 0) - kfree(airq); + + ret = register_airq(airq, isc); out: snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%d", ret); CIO_TRACE_EVENT(4, dbf_txt); - if (ret < 0) + if (ret < 0) { + kfree(airq); return ERR_PTR(ret); - else - return &indicators.byte[ret]; + } else + return &indicators[isc].byte[ret]; } EXPORT_SYMBOL(s390_register_adapter_interrupt); /** * s390_unregister_adapter_interrupt - unregister adapter interrupt handler * @ind: indicator for which the handler is to be unregistered + * @isc: interruption subclass */ -void s390_unregister_adapter_interrupt(void *ind) +void s390_unregister_adapter_interrupt(void *ind, u8 isc) { struct airq_t *airq; char dbf_txt[16]; int i; - i = (int) ((addr_t) ind) - ((addr_t) &indicators.byte[0]); + i = (int) ((addr_t) ind) - ((addr_t) &indicators[isc].byte[0]); snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%d", i); CIO_TRACE_EVENT(4, dbf_txt); - indicators.byte[i] = 0; - airq = xchg(&airqs[i], NULL); + indicators[isc].byte[i] = 0; + airq = xchg(&airqs[isc][i], NULL); /* * Allow interrupts to complete. This will ensure that the airq handle * is no longer referenced by any interrupt handler. @@ -108,7 +113,7 @@ EXPORT_SYMBOL(s390_unregister_adapter_interrupt); #define INDICATOR_MASK (0xffUL << ((NR_AIRQS_PER_WORD - 1) * 8)) -void do_adapter_IO(void) +void do_adapter_IO(u8 isc) { int w; int i; @@ -120,22 +125,22 @@ void do_adapter_IO(void) * fetch operations. */ for (w = 0; w < NR_AIRQ_WORDS; w++) { - word = indicators.word[w]; + word = indicators[isc].word[w]; i = w * NR_AIRQS_PER_WORD; /* * Check bytes within word for active indicators. */ while (word) { if (word & INDICATOR_MASK) { - airq = airqs[i]; + airq = airqs[isc][i]; if (likely(airq)) - airq->handler(&indicators.byte[i], + airq->handler(&indicators[isc].byte[i], airq->drv_data); else /* * Reset ill-behaved indicator. */ - indicators.byte[i] = 0; + indicators[isc].byte[i] = 0; } word <<= 8; i++; diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index a4f9130910d..bf616daeff4 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -641,7 +641,7 @@ do_IRQ (struct pt_regs *regs) */ if (tpi_info->adapter_IO == 1 && tpi_info->int_type == IO_INTERRUPT_TYPE) { - do_adapter_IO(); + do_adapter_IO(tpi_info->isc); continue; } sch = (struct subchannel *)(unsigned long)tpi_info->intparm; diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 49ee6395116..2e7e571d120 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -106,7 +106,7 @@ int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); int cio_tm_intrg(struct subchannel *sch); int cio_create_sch_lock(struct subchannel *); -void do_adapter_IO(void); +void do_adapter_IO(u8 isc); void do_IRQ(struct pt_regs *); /* Use with care. */ diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index f9be265e7e8..8476f8c35c2 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -3713,7 +3713,8 @@ tiqdio_register_thinints(void) char dbf_text[20]; tiqdio_ind = - s390_register_adapter_interrupt(&tiqdio_thinint_handler, NULL); + 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); @@ -3729,7 +3730,8 @@ static void tiqdio_unregister_thinints(void) { if (tiqdio_ind) - s390_unregister_adapter_interrupt(tiqdio_ind); + s390_unregister_adapter_interrupt(tiqdio_ind, + TIQDIO_THININT_ISC); } static int diff --git a/include/asm-s390/airq.h b/include/asm-s390/airq.h index 41d028cb52a..1ac80d6b058 100644 --- a/include/asm-s390/airq.h +++ b/include/asm-s390/airq.h @@ -13,7 +13,7 @@ typedef void (*adapter_int_handler_t)(void *, void *); -void *s390_register_adapter_interrupt(adapter_int_handler_t, void *); -void s390_unregister_adapter_interrupt(void *); +void *s390_register_adapter_interrupt(adapter_int_handler_t, void *, u8); +void s390_unregister_adapter_interrupt(void *, u8); #endif /* _ASM_S390_AIRQ_H */ -- GitLab From fcc6ab335ba4d0f2b2548a910466c0dac767e5b1 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 14 Jul 2008 09:59:00 +0200 Subject: [PATCH 1767/2509] [S390] cio: introduce isc_(un)register functions. This interface makes it easy for drivers to register usage of different I/O interruption subclasses without needing to worry about possible other users of the same isc. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/Makefile | 4 +-- drivers/s390/cio/isc.c | 68 +++++++++++++++++++++++++++++++++++++++ include/asm-s390/isc.h | 6 ++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 drivers/s390/cio/isc.c diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index e199c927b7a..6735ebb3c98 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -2,8 +2,8 @@ # Makefile for the S/390 common i/o drivers # -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o \ - itcw.o +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \ + fcx.o itcw.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o diff --git a/drivers/s390/cio/isc.c b/drivers/s390/cio/isc.c new file mode 100644 index 00000000000..c592087be0f --- /dev/null +++ b/drivers/s390/cio/isc.c @@ -0,0 +1,68 @@ +/* + * Functions for registration of I/O interruption subclasses on s390. + * + * Copyright IBM Corp. 2008 + * Authors: Sebastian Ott + */ + +#include +#include +#include + +static unsigned int isc_refs[MAX_ISC + 1]; +static DEFINE_SPINLOCK(isc_ref_lock); + + +/** + * isc_register - register an I/O interruption subclass. + * @isc: I/O interruption subclass to register + * + * The number of users for @isc is increased. If this is the first user to + * register @isc, the corresponding I/O interruption subclass mask is enabled. + * + * Context: + * This function must not be called in interrupt context. + */ +void isc_register(unsigned int isc) +{ + if (isc > MAX_ISC) { + WARN_ON(1); + return; + } + + spin_lock(&isc_ref_lock); + if (isc_refs[isc] == 0) + ctl_set_bit(6, 31 - isc); + isc_refs[isc]++; + spin_unlock(&isc_ref_lock); +} +EXPORT_SYMBOL_GPL(isc_register); + +/** + * isc_unregister - unregister an I/O interruption subclass. + * @isc: I/O interruption subclass to unregister + * + * The number of users for @isc is decreased. If this is the last user to + * unregister @isc, the corresponding I/O interruption subclass mask is + * disabled. + * Note: This function must not be called if isc_register() hasn't been called + * before by the driver for @isc. + * + * Context: + * This function must not be called in interrupt context. + */ +void isc_unregister(unsigned int isc) +{ + spin_lock(&isc_ref_lock); + /* check for misuse */ + if (isc > MAX_ISC || isc_refs[isc] == 0) { + WARN_ON(1); + goto out_unlock; + } + if (isc_refs[isc] == 1) + ctl_clear_bit(6, 31 - isc); + isc_refs[isc]--; +out_unlock: + spin_unlock(&isc_ref_lock); +} +EXPORT_SYMBOL_GPL(isc_unregister); diff --git a/include/asm-s390/isc.h b/include/asm-s390/isc.h index 533a1372234..fe56f7b445e 100644 --- a/include/asm-s390/isc.h +++ b/include/asm-s390/isc.h @@ -1,6 +1,8 @@ #ifndef _ASM_S390_ISC_H #define _ASM_S390_ISC_H +#include + /* * I/O interruption subclasses used by drivers. * Please add all used iscs here so that it is possible to distribute @@ -15,4 +17,8 @@ /* Adapter interrupts. */ #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ +/* Functions for registration of I/O interruption subclasses */ +void isc_register(unsigned int isc); +void isc_unregister(unsigned int isc); + #endif /* _ASM_S390_ISC_H */ -- GitLab From 6ef556ccc8fd256259745c4f0d0ab65aaf703824 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:59:01 +0200 Subject: [PATCH 1768/2509] [S390] cio: Use isc_{register,unregister}. Use the new isc registration functions for all places that need an I/O interruption subclass. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/cio.c | 5 +++-- drivers/s390/cio/css.c | 2 +- drivers/s390/cio/qdio.c | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index bf616daeff4..34b38fb7c2f 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -786,12 +786,13 @@ cio_probe_console(void) /* * enable console I/O-interrupt subclass */ - ctl_set_bit(6, 31 - CONSOLE_ISC); + isc_register(CONSOLE_ISC); console_subchannel.schib.pmcw.isc = CONSOLE_ISC; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; ret = cio_modify(&console_subchannel); if (ret) { + isc_unregister(CONSOLE_ISC); console_subchannel_in_use = 0; return ERR_PTR(ret); } @@ -803,7 +804,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm = 0; cio_modify(&console_subchannel); - ctl_clear_bit(6, 31 - CONSOLE_ISC); + isc_unregister(CONSOLE_ISC); console_subchannel_in_use = 0; } diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index b24618b5362..45ba07c0a28 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -806,7 +806,7 @@ init_channel_subsystem (void) css_init_done = 1; /* Enable default isc for I/O subchannels. */ - ctl_set_bit(6, 31 - IO_SCH_ISC); + isc_register(IO_SCH_ISC); for_each_subchannel(__init_channel_subsystem, NULL); return 0; diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 8476f8c35c2..2bf36e14b10 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -3892,6 +3892,7 @@ init_QDIO(void) qdio_mempool_alloc, qdio_mempool_free, NULL); + isc_register(QDIO_AIRQ_ISC); if (tiqdio_check_chsc_availability()) QDIO_PRINT_ERR("Not all CHSCs supported. Continuing.\n"); @@ -3904,6 +3905,7 @@ static void __exit cleanup_QDIO(void) { tiqdio_unregister_thinints(); + isc_unregister(QDIO_AIRQ_ISC); qdio_remove_procfs_entry(); qdio_release_qdio_memory(); qdio_unregister_dbf_views(); -- GitLab From 99611f87176b2a908d8c66ab19a5fc550a3cd13a Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:59:02 +0200 Subject: [PATCH 1769/2509] [S390] cio: Repair chpid event handling. Passing the affected chpid in chp_event() worked only by chance since chpid is the first element in res_acc_data. Make it work properly by generalizing res_acc_data as chp_link and always passing around a properly filled out chp_link structure in chp_event(). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 6 ++--- drivers/s390/cio/chp.h | 4 +-- drivers/s390/cio/chsc.c | 55 ++++++++++++++++++++++----------------- drivers/s390/cio/css.h | 3 ++- drivers/s390/cio/device.c | 11 ++++---- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 62df43b2124..19078d52885 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -525,7 +525,7 @@ static void chp_process_crw(struct crw *crw0, struct crw *crw1, } } -int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) +int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct chp_link *link) { int i; int mask; @@ -534,10 +534,10 @@ int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) mask = 0x80 >> i; if (!(ssd->path_mask & mask)) continue; - if (!chp_id_is_equal(&ssd->chpid[i], &data->chpid)) + if (!chp_id_is_equal(&ssd->chpid[i], &link->chpid)) continue; if ((ssd->fla_valid_mask & mask) && - ((ssd->fla[i] & data->fla_mask) != data->fla)) + ((ssd->fla[i] & link->fla_mask) != link->fla)) continue; return mask; } diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index dffe2771dda..26c3d224617 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -24,7 +24,7 @@ #define CHP_VARY_ON 2 #define CHP_VARY_OFF 3 -struct res_acc_data { +struct chp_link { struct chp_id chpid; u32 fla_mask; u16 fla; @@ -60,5 +60,5 @@ int chp_new(struct chp_id chpid); void chp_cfg_schedule(struct chp_id chpid, int configure); void chp_cfg_cancel_deconfigure(struct chp_id chpid); int chp_info_get_status(struct chp_id chpid); -int chp_ssd_get_mask(struct chsc_ssd_info *, struct res_acc_data *); +int chp_ssd_get_mask(struct chsc_ssd_info *, struct chp_link *); #endif /* S390_CHP_H */ diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 62b0b16fe3d..e23c3806972 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -146,15 +146,18 @@ out_unreg: void chsc_chp_offline(struct chp_id chpid) { char dbf_txt[15]; + struct chp_link link; sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) <= 0) return; + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); - for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); + for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link); } static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) @@ -187,15 +190,15 @@ static int __s390_process_res_acc(struct subchannel *sch, void *data) return 0; } -static void s390_process_res_acc (struct res_acc_data *res_data) +static void s390_process_res_acc(struct chp_link *link) { char dbf_txt[15]; - sprintf(dbf_txt, "accpr%x.%02x", res_data->chpid.cssid, - res_data->chpid.id); + sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid, + link->chpid.id); CIO_TRACE_EVENT( 2, dbf_txt); - if (res_data->fla != 0) { - sprintf(dbf_txt, "fla%x", res_data->fla); + if (link->fla != 0) { + sprintf(dbf_txt, "fla%x", link->fla); CIO_TRACE_EVENT( 2, dbf_txt); } /* Wait until previous actions have settled. */ @@ -208,7 +211,7 @@ static void s390_process_res_acc (struct res_acc_data *res_data) * will we have to do. */ for_each_subchannel_staged(__s390_process_res_acc, - s390_process_res_acc_new_sch, res_data); + s390_process_res_acc_new_sch, link); } static int @@ -281,7 +284,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) { - struct res_acc_data res_data; + struct chp_link link; struct chp_id chpid; int status; @@ -297,18 +300,18 @@ static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) chp_new(chpid); else if (!status) return; - memset(&res_data, 0, sizeof(struct res_acc_data)); - res_data.chpid = chpid; + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; if ((sei_area->vf & 0xc0) != 0) { - res_data.fla = sei_area->fla; + link.fla = sei_area->fla; if ((sei_area->vf & 0xc0) == 0xc0) /* full link address */ - res_data.fla_mask = 0xffff; + link.fla_mask = 0xffff; else /* link address */ - res_data.fla_mask = 0xff00; + link.fla_mask = 0xff00; } - s390_process_res_acc(&res_data); + s390_process_res_acc(&link); } struct chp_config_data { @@ -413,18 +416,18 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) void chsc_chp_online(struct chp_id chpid) { char dbf_txt[15]; - struct res_acc_data res_data; + struct chp_link link; sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) != 0) { - memset(&res_data, 0, sizeof(struct res_acc_data)); - res_data.chpid = chpid; + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); for_each_subchannel_staged(__s390_process_res_acc, NULL, - &res_data); + &link); } } @@ -432,13 +435,13 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, struct chp_id chpid, int on) { unsigned long flags; - struct res_acc_data res_data; + struct chp_link link; - memset(&res_data, 0, sizeof(struct res_acc_data)); - res_data.chpid = chpid; + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; spin_lock_irqsave(sch->lock, flags); if (sch->driver && sch->driver->chp_event) - sch->driver->chp_event(sch, &res_data, + sch->driver->chp_event(sch, &link, on ? CHP_VARY_ON : CHP_VARY_OFF); spin_unlock_irqrestore(sch->lock, flags); } @@ -479,6 +482,10 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data) */ int chsc_chp_vary(struct chp_id chpid, int on) { + struct chp_link link; + + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); /* @@ -487,10 +494,10 @@ int chsc_chp_vary(struct chp_id chpid, int on) if (on) for_each_subchannel_staged(s390_subchannel_vary_chpid_on, - __s390_vary_chpid_on, &chpid); + __s390_vary_chpid_on, &link); else for_each_subchannel_staged(s390_subchannel_vary_chpid_off, - NULL, &chpid); + NULL, &link); return 0; } diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 3ec3dc5a1e5..38bf9ddb841 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -59,6 +59,7 @@ struct pgid { } __attribute__ ((packed)); struct subchannel; +struct chp_link; /** * struct css_driver - device driver for subchannels * @owner: owning module @@ -77,7 +78,7 @@ struct css_driver { unsigned int subchannel_type; struct device_driver drv; void (*irq)(struct subchannel *); - int (*chp_event)(struct subchannel *, void *, int); + int (*chp_event)(struct subchannel *, struct chp_link *, int); int (*sch_event)(struct subchannel *, int); int (*probe)(struct subchannel *); int (*remove)(struct subchannel *); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 67e7a312395..522d47afc95 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -128,7 +128,8 @@ static int io_subchannel_probe(struct subchannel *); static int io_subchannel_remove(struct subchannel *); static void io_subchannel_shutdown(struct subchannel *); static int io_subchannel_sch_event(struct subchannel *, int); -static int io_subchannel_chp_event(struct subchannel *, void *, int); +static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, + int); static struct css_driver io_subchannel_driver = { .owner = THIS_MODULE, @@ -1329,14 +1330,12 @@ static void io_subchannel_terminate_path(struct subchannel *sch, u8 mask) } -static int io_subchannel_chp_event(struct subchannel *sch, void *data, - int event) +static int io_subchannel_chp_event(struct subchannel *sch, + struct chp_link *link, int event) { int mask; - struct res_acc_data *res_data; - res_data = data; - mask = chp_ssd_get_mask(&sch->ssd_info, res_data); + mask = chp_ssd_get_mask(&sch->ssd_info, link); if (!mask) return 0; switch (event) { -- GitLab From f08adc008d84f6b03d377ede951e29ed169e76e2 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:59:03 +0200 Subject: [PATCH 1770/2509] [S390] css: Use css_device_id for bus matching. css_device_id exists, so use it for determining the right driver (and add a match_flags which is always 1 for valid types). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/css.c | 15 ++++++--------- drivers/s390/cio/css.h | 2 +- drivers/s390/cio/device.c | 8 +++++++- include/linux/mod_devicetable.h | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 45ba07c0a28..4e2f2bbf4ba 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -850,19 +850,16 @@ int sch_is_pseudo_sch(struct subchannel *sch) return sch == to_css(sch->dev.parent)->pseudo_subchannel; } -/* - * find a driver for a subchannel. They identify by the subchannel - * type with the exception that the console subchannel driver has its own - * subchannel type although the device is an i/o subchannel - */ -static int -css_bus_match (struct device *dev, struct device_driver *drv) +static int css_bus_match(struct device *dev, struct device_driver *drv) { struct subchannel *sch = to_subchannel(dev); struct css_driver *driver = to_cssdriver(drv); + struct css_device_id *id; - if (sch->st == driver->subchannel_type) - return 1; + for (id = driver->subchannel_type; id->match_flags; id++) { + if (sch->st == id->type) + return 1; + } return 0; } diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 38bf9ddb841..58020bf41ed 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -75,7 +75,7 @@ struct chp_link; */ struct css_driver { struct module *owner; - unsigned int subchannel_type; + struct css_device_id *subchannel_type; struct device_driver drv; void (*irq)(struct subchannel *); int (*chp_event)(struct subchannel *, struct chp_link *, int); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 522d47afc95..c904cb84d75 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -131,9 +131,15 @@ static int io_subchannel_sch_event(struct subchannel *, int); static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, int); +static struct css_device_id io_subchannel_ids[] = { + { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(css, io_subchannel_ids); + static struct css_driver io_subchannel_driver = { .owner = THIS_MODULE, - .subchannel_type = SUBCHANNEL_TYPE_IO, + .subchannel_type = io_subchannel_ids, .name = "io_subchannel", .irq = io_subchannel_irq, .sch_event = io_subchannel_sch_event, diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 1fd03e732e0..c4db5827963 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -161,8 +161,8 @@ struct ap_device_id { /* s390 css bus devices (subchannels) */ struct css_device_id { + __u8 match_flags; __u8 type; /* subchannel type */ - __u8 pad1; __u16 pad2; __u32 pad3; kernel_ulong_t driver_data; -- GitLab From 683c5418e6ac9f40f925dab6f547a5b0a4ad43c6 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:59:04 +0200 Subject: [PATCH 1771/2509] [S390] cio: suppress chpid event in case of configure error Do not send CHP_ONLINE/CHP_OFFLINE events to subchannel drivers when a channel-path configure request failed. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 19078d52885..e40eda0ed46 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -624,6 +624,7 @@ static void cfg_func(struct work_struct *work) { struct chp_id chpid; enum cfg_task_t t; + int rc; mutex_lock(&cfg_lock); t = cfg_none; @@ -638,14 +639,24 @@ static void cfg_func(struct work_struct *work) switch (t) { case cfg_configure: - sclp_chp_configure(chpid); - info_expire(); - chsc_chp_online(chpid); + rc = sclp_chp_configure(chpid); + if (rc) + CIO_MSG_EVENT(2, "chp: sclp_chp_configure(%x.%02x)=" + "%d\n", chpid.cssid, chpid.id, rc); + else { + info_expire(); + chsc_chp_online(chpid); + } break; case cfg_deconfigure: - sclp_chp_deconfigure(chpid); - info_expire(); - chsc_chp_offline(chpid); + rc = sclp_chp_deconfigure(chpid); + if (rc) + CIO_MSG_EVENT(2, "chp: sclp_chp_deconfigure(%x.%02x)=" + "%d\n", chpid.cssid, chpid.id, rc); + else { + info_expire(); + chsc_chp_offline(chpid); + } break; case cfg_none: /* Get updated information after last change. */ -- GitLab From 9d92a7e1b0d095c8be96ce5e592c6c5541684631 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 14 Jul 2008 09:59:05 +0200 Subject: [PATCH 1772/2509] [S390] cio: Add chsc subchannel driver. This patch adds a driver for subchannels of type chsc. A device /dev/chsc is created which may be used to issue ioctls to: - obtain information about the machine's I/O configuration - dynamically change the machine's I/O configuration via asynchronous chsc commands Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- Documentation/ioctl-number.txt | 1 + arch/s390/Kconfig | 16 + drivers/s390/cio/Makefile | 1 + drivers/s390/cio/chp.c | 2 +- drivers/s390/cio/chsc.c | 48 +- drivers/s390/cio/chsc.h | 21 +- drivers/s390/cio/chsc_sch.c | 820 ++++++++++++++++++ drivers/s390/cio/chsc_sch.h | 13 + drivers/s390/cio/cio.c | 9 + drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/css.h | 3 +- drivers/s390/cio/idset.h | 2 +- drivers/s390/cio/io_sch.h | 2 +- drivers/s390/cio/ioasm.h | 2 +- drivers/s390/cio/qdio.h | 3 +- include/asm-s390/Kbuild | 3 + include/asm-s390/chpid.h | 5 +- include/asm-s390/chsc.h | 127 +++ include/asm-s390/isc.h | 1 + .../s390/cio => include/asm-s390}/schid.h | 18 +- 20 files changed, 1068 insertions(+), 31 deletions(-) create mode 100644 drivers/s390/cio/chsc_sch.c create mode 100644 drivers/s390/cio/chsc_sch.h create mode 100644 include/asm-s390/chsc.h rename {drivers/s390/cio => include/asm-s390}/schid.h (65%) diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index 240ce7a56c4..3bb5f466a90 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -117,6 +117,7 @@ Code Seq# Include File Comments 'c' 00-7F linux/comstats.h conflict! 'c' 00-7F linux/coda.h conflict! +'c' 80-9F asm-s390/chsc.h 'd' 00-FF linux/char/drm/drm/h conflict! 'd' 00-DF linux/video_decoder.h conflict! 'd' F0-FF linux/digi1.h diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a79820c3ab0..6d0d31651f0 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -345,6 +345,22 @@ config QDIO_DEBUG If unsure, say N. +config CHSC_SCH + tristate "Support for CHSC subchannels" + help + This driver allows usage of CHSC subchannels. A CHSC subchannel + is usually present on LPAR only. + The driver creates a device /dev/chsc, which may be used to + obtain I/O configuration information about the machine and + to issue asynchronous chsc commands (DANGEROUS). + You will usually only want to use this interface on a special + LPAR designated for system management. + + To compile this driver as a module, choose M here: the + module will be called chsc_sch. + + If unsure, say N. + comment "Misc" config IPL diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 6735ebb3c98..91e9e3f3073 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -7,5 +7,6 @@ obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \ ccw_device-objs += device.o device_fsm.o device_ops.o 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 obj-$(CONFIG_QDIO) += qdio.o diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index e40eda0ed46..8644c80a205 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -407,7 +407,7 @@ int chp_new(struct chp_id chpid) chpid.id); /* Obtain channel path description and fill it in. */ - ret = chsc_determine_channel_path_description(chpid, &chp->desc); + ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); if (ret) goto out_free; if ((chp->desc.flags & 0x80) == 0) { diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index e23c3806972..65264a38057 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -15,6 +15,7 @@ #include #include +#include #include "../s390mach.h" #include "css.h" @@ -627,23 +628,33 @@ chsc_secm(struct channel_subsystem *css, int enable) return ret; } -int chsc_determine_channel_path_description(struct chp_id chpid, - struct channel_path_desc *desc) +int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, + int c, int m, + struct chsc_response_struct *resp) { int ccode, ret; struct { struct chsc_header request; - u32 : 24; + u32 : 2; + u32 m : 1; + u32 c : 1; + u32 fmt : 4; + u32 cssid : 8; + u32 : 4; + u32 rfmt : 4; u32 first_chpid : 8; u32 : 24; u32 last_chpid : 8; u32 zeroes1; struct chsc_header response; - u32 zeroes2; - struct channel_path_desc desc; + u8 data[PAGE_SIZE - 20]; } __attribute__ ((packed)) *scpd_area; + if ((rfmt == 1) && !css_general_characteristics.fcs) + return -EINVAL; + if ((rfmt == 2) && !css_general_characteristics.cib) + return -EINVAL; scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!scpd_area) return -ENOMEM; @@ -651,8 +662,13 @@ int chsc_determine_channel_path_description(struct chp_id chpid, scpd_area->request.length = 0x0010; scpd_area->request.code = 0x0002; + scpd_area->cssid = chpid.cssid; scpd_area->first_chpid = chpid.id; scpd_area->last_chpid = chpid.id; + scpd_area->m = m; + scpd_area->c = c; + scpd_area->fmt = fmt; + scpd_area->rfmt = rfmt; ccode = chsc(scpd_area); if (ccode > 0) { @@ -663,8 +679,7 @@ int chsc_determine_channel_path_description(struct chp_id chpid, ret = chsc_error_from_response(scpd_area->response.code); if (ret == 0) /* Success. */ - memcpy(desc, &scpd_area->desc, - sizeof(struct channel_path_desc)); + memcpy(resp, &scpd_area->response, scpd_area->response.length); else CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n", scpd_area->response.code); @@ -672,6 +687,25 @@ out: free_page((unsigned long)scpd_area); return ret; } +EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc); + +int chsc_determine_base_channel_path_desc(struct chp_id chpid, + struct channel_path_desc *desc) +{ + struct chsc_response_struct *chsc_resp; + int ret; + + chsc_resp = kzalloc(sizeof(*chsc_resp), GFP_KERNEL); + if (!chsc_resp) + return -ENOMEM; + ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp); + if (ret) + goto out_free; + memcpy(desc, &chsc_resp->data, chsc_resp->length); +out_free: + kfree(chsc_resp); + return ret; +} static void chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 2a38b509022..fb6c4d6c45b 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -4,7 +4,8 @@ #include #include #include -#include "schid.h" +#include +#include #define CHSC_SDA_OC_MSS 0x2 @@ -37,11 +38,14 @@ struct channel_path_desc { struct channel_path; struct css_general_char { - u64 : 41; + u64 : 12; + u32 dynio : 1; /* bit 12 */ + u32 : 28; u32 aif : 1; /* bit 41 */ u32 : 3; u32 mcss : 1; /* bit 45 */ - u32 : 2; + u32 fcs : 1; /* bit 46 */ + u32 : 1; u32 ext_mb : 1; /* bit 48 */ u32 : 7; u32 aif_tdd : 1; /* bit 56 */ @@ -49,7 +53,9 @@ struct css_general_char { u32 qebsm : 1; /* bit 58 */ u32 : 8; u32 aif_osa : 1; /* bit 67 */ - u32 : 20; + u32 : 14; + u32 cib : 1; /* bit 82 */ + u32 : 5; u32 fcx : 1; /* bit 88 */ u32 : 7; }__attribute__((packed)); @@ -86,8 +92,11 @@ struct channel_subsystem; extern int chsc_secm(struct channel_subsystem *, int); int chsc_chp_vary(struct chp_id chpid, int on); -int chsc_determine_channel_path_description(struct chp_id chpid, - struct channel_path_desc *desc); +int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, + int c, int m, + struct chsc_response_struct *resp); +int chsc_determine_base_channel_path_desc(struct chp_id chpid, + struct channel_path_desc *desc); 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); diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c new file mode 100644 index 00000000000..91ca87aa9f9 --- /dev/null +++ b/drivers/s390/cio/chsc_sch.c @@ -0,0 +1,820 @@ +/* + * Driver for s390 chsc subchannels + * + * Copyright IBM Corp. 2008 + * Author(s): Cornelia Huck + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "cio.h" +#include "cio_debug.h" +#include "css.h" +#include "chsc_sch.h" +#include "ioasm.h" + +static debug_info_t *chsc_debug_msg_id; +static debug_info_t *chsc_debug_log_id; + +#define CHSC_MSG(imp, args...) do { \ + debug_sprintf_event(chsc_debug_msg_id, imp , ##args); \ + } while (0) + +#define CHSC_LOG(imp, txt) do { \ + debug_text_event(chsc_debug_log_id, imp , txt); \ + } while (0) + +static void CHSC_LOG_HEX(int level, void *data, int length) +{ + while (length > 0) { + debug_event(chsc_debug_log_id, level, data, length); + length -= chsc_debug_log_id->buf_size; + data += chsc_debug_log_id->buf_size; + } +} + +MODULE_AUTHOR("IBM Corporation"); +MODULE_DESCRIPTION("driver for s390 chsc subchannels"); +MODULE_LICENSE("GPL"); + +static void chsc_subchannel_irq(struct subchannel *sch) +{ + struct chsc_private *private = sch->private; + struct chsc_request *request = private->request; + struct irb *irb = (struct irb *)__LC_IRB; + + CHSC_LOG(4, "irb"); + CHSC_LOG_HEX(4, irb, sizeof(*irb)); + /* Copy irb to provided request and set done. */ + if (!request) { + CHSC_MSG(0, "Interrupt on sch 0.%x.%04x with no request\n", + sch->schid.ssid, sch->schid.sch_no); + return; + } + private->request = NULL; + memcpy(&request->irb, irb, sizeof(*irb)); + stsch(sch->schid, &sch->schib); + complete(&request->completion); + put_device(&sch->dev); +} + +static int chsc_subchannel_probe(struct subchannel *sch) +{ + struct chsc_private *private; + int ret; + + CHSC_MSG(6, "Detected chsc subchannel 0.%x.%04x\n", + sch->schid.ssid, sch->schid.sch_no); + sch->isc = CHSC_SCH_ISC; + private = kzalloc(sizeof(*private), GFP_KERNEL); + if (!private) + return -ENOMEM; + ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); + if (ret) { + CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", + sch->schid.ssid, sch->schid.sch_no, ret); + kfree(private); + } else { + sch->private = private; + if (sch->dev.uevent_suppress) { + sch->dev.uevent_suppress = 0; + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } + } + return ret; +} + +static int chsc_subchannel_remove(struct subchannel *sch) +{ + struct chsc_private *private; + + cio_disable_subchannel(sch); + private = sch->private; + sch->private = NULL; + if (private->request) { + complete(&private->request->completion); + put_device(&sch->dev); + } + kfree(private); + return 0; +} + +static void chsc_subchannel_shutdown(struct subchannel *sch) +{ + cio_disable_subchannel(sch); +} + +static struct css_device_id chsc_subchannel_ids[] = { + { .match_flags = 0x1, .type =SUBCHANNEL_TYPE_CHSC, }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(css, chsc_subchannel_ids); + +static struct css_driver chsc_subchannel_driver = { + .owner = THIS_MODULE, + .subchannel_type = chsc_subchannel_ids, + .irq = chsc_subchannel_irq, + .probe = chsc_subchannel_probe, + .remove = chsc_subchannel_remove, + .shutdown = chsc_subchannel_shutdown, + .name = "chsc_subchannel", +}; + +static int __init chsc_init_dbfs(void) +{ + chsc_debug_msg_id = debug_register("chsc_msg", 16, 1, + 16 * sizeof(long)); + if (!chsc_debug_msg_id) + goto out; + debug_register_view(chsc_debug_msg_id, &debug_sprintf_view); + debug_set_level(chsc_debug_msg_id, 2); + chsc_debug_log_id = debug_register("chsc_log", 16, 1, 16); + if (!chsc_debug_log_id) + goto out; + debug_register_view(chsc_debug_log_id, &debug_hex_ascii_view); + debug_set_level(chsc_debug_log_id, 2); + return 0; +out: + if (chsc_debug_msg_id) + debug_unregister(chsc_debug_msg_id); + return -ENOMEM; +} + +static void chsc_remove_dbfs(void) +{ + debug_unregister(chsc_debug_log_id); + debug_unregister(chsc_debug_msg_id); +} + +static int __init chsc_init_sch_driver(void) +{ + return css_driver_register(&chsc_subchannel_driver); +} + +static void chsc_cleanup_sch_driver(void) +{ + css_driver_unregister(&chsc_subchannel_driver); +} + +static DEFINE_SPINLOCK(chsc_lock); + +static int chsc_subchannel_match_next_free(struct device *dev, void *data) +{ + struct subchannel *sch = to_subchannel(dev); + + return sch->schib.pmcw.ena && !scsw_fctl(&sch->schib.scsw); +} + +static struct subchannel *chsc_get_next_subchannel(struct subchannel *sch) +{ + struct device *dev; + + dev = driver_find_device(&chsc_subchannel_driver.drv, + sch ? &sch->dev : NULL, NULL, + chsc_subchannel_match_next_free); + return dev ? to_subchannel(dev) : NULL; +} + +/** + * chsc_async() - try to start a chsc request asynchronously + * @chsc_area: request to be started + * @request: request structure to associate + * + * Tries to start a chsc request on one of the existing chsc subchannels. + * Returns: + * %0 if the request was performed synchronously + * %-EINPROGRESS if the request was successfully started + * %-EBUSY if all chsc subchannels are busy + * %-ENODEV if no chsc subchannels are available + * Context: + * interrupts disabled, chsc_lock held + */ +static int chsc_async(struct chsc_async_area *chsc_area, + struct chsc_request *request) +{ + int cc; + struct chsc_private *private; + struct subchannel *sch = NULL; + int ret = -ENODEV; + char dbf[10]; + + chsc_area->header.key = PAGE_DEFAULT_KEY; + while ((sch = chsc_get_next_subchannel(sch))) { + spin_lock(sch->lock); + private = sch->private; + if (private->request) { + spin_unlock(sch->lock); + ret = -EBUSY; + continue; + } + chsc_area->header.sid = sch->schid; + CHSC_LOG(2, "schid"); + CHSC_LOG_HEX(2, &sch->schid, sizeof(sch->schid)); + cc = chsc(chsc_area); + sprintf(dbf, "cc:%d", cc); + CHSC_LOG(2, dbf); + switch (cc) { + case 0: + ret = 0; + break; + case 1: + sch->schib.scsw.cmd.fctl |= SCSW_FCTL_START_FUNC; + ret = -EINPROGRESS; + private->request = request; + break; + case 2: + ret = -EBUSY; + break; + default: + ret = -ENODEV; + } + spin_unlock(sch->lock); + CHSC_MSG(2, "chsc on 0.%x.%04x returned cc=%d\n", + sch->schid.ssid, sch->schid.sch_no, cc); + if (ret == -EINPROGRESS) + return -EINPROGRESS; + put_device(&sch->dev); + if (ret == 0) + return 0; + } + return ret; +} + +static void chsc_log_command(struct chsc_async_area *chsc_area) +{ + char dbf[10]; + + sprintf(dbf, "CHSC:%x", chsc_area->header.code); + CHSC_LOG(0, dbf); + CHSC_LOG_HEX(0, chsc_area, 32); +} + +static int chsc_examine_irb(struct chsc_request *request) +{ + int backed_up; + + if (!scsw_stctl(&request->irb.scsw) & SCSW_STCTL_STATUS_PEND) + return -EIO; + backed_up = scsw_cstat(&request->irb.scsw) & SCHN_STAT_CHAIN_CHECK; + request->irb.scsw.cmd.cstat &= ~SCHN_STAT_CHAIN_CHECK; + if (scsw_cstat(&request->irb.scsw) == 0) + return 0; + if (!backed_up) + return 0; + if (scsw_cstat(&request->irb.scsw) & SCHN_STAT_PROG_CHECK) + return -EIO; + if (scsw_cstat(&request->irb.scsw) & SCHN_STAT_PROT_CHECK) + return -EPERM; + if (scsw_cstat(&request->irb.scsw) & SCHN_STAT_CHN_DATA_CHK) + return -EAGAIN; + if (scsw_cstat(&request->irb.scsw) & SCHN_STAT_CHN_CTRL_CHK) + return -EAGAIN; + return -EIO; +} + +static int chsc_ioctl_start(void __user *user_area) +{ + struct chsc_request *request; + struct chsc_async_area *chsc_area; + int ret; + char dbf[10]; + + if (!css_general_characteristics.dynio) + /* It makes no sense to try. */ + return -EOPNOTSUPP; + chsc_area = (void *)get_zeroed_page(GFP_DMA | GFP_KERNEL); + if (!chsc_area) + return -ENOMEM; + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (!request) { + ret = -ENOMEM; + goto out_free; + } + init_completion(&request->completion); + if (copy_from_user(chsc_area, user_area, PAGE_SIZE)) { + ret = -EFAULT; + goto out_free; + } + chsc_log_command(chsc_area); + spin_lock_irq(&chsc_lock); + ret = chsc_async(chsc_area, request); + spin_unlock_irq(&chsc_lock); + if (ret == -EINPROGRESS) { + wait_for_completion(&request->completion); + ret = chsc_examine_irb(request); + } + /* copy area back to user */ + if (!ret) + if (copy_to_user(user_area, chsc_area, PAGE_SIZE)) + ret = -EFAULT; +out_free: + sprintf(dbf, "ret:%d", ret); + CHSC_LOG(0, dbf); + kfree(request); + free_page((unsigned long)chsc_area); + return ret; +} + +static int chsc_ioctl_info_channel_path(void __user *user_cd) +{ + struct chsc_chp_cd *cd; + int ret, ccode; + struct { + struct chsc_header request; + u32 : 2; + u32 m : 1; + u32 : 1; + u32 fmt1 : 4; + u32 cssid : 8; + u32 : 8; + u32 first_chpid : 8; + u32 : 24; + u32 last_chpid : 8; + u32 : 32; + struct chsc_header response; + u8 data[PAGE_SIZE - 20]; + } __attribute__ ((packed)) *scpcd_area; + + scpcd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!scpcd_area) + return -ENOMEM; + cd = kzalloc(sizeof(*cd), GFP_KERNEL); + if (!cd) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(cd, user_cd, sizeof(*cd))) { + ret = -EFAULT; + goto out_free; + } + scpcd_area->request.length = 0x0010; + scpcd_area->request.code = 0x0028; + scpcd_area->m = cd->m; + scpcd_area->fmt1 = cd->fmt; + scpcd_area->cssid = cd->chpid.cssid; + scpcd_area->first_chpid = cd->chpid.id; + scpcd_area->last_chpid = cd->chpid.id; + + ccode = chsc(scpcd_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (scpcd_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "scpcd: response code=%x\n", + scpcd_area->response.code); + goto out_free; + } + memcpy(&cd->cpcb, &scpcd_area->response, scpcd_area->response.length); + if (copy_to_user(user_cd, cd, sizeof(*cd))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(cd); + free_page((unsigned long)scpcd_area); + return ret; +} + +static int chsc_ioctl_info_cu(void __user *user_cd) +{ + struct chsc_cu_cd *cd; + int ret, ccode; + struct { + struct chsc_header request; + u32 : 2; + u32 m : 1; + u32 : 1; + u32 fmt1 : 4; + u32 cssid : 8; + u32 : 8; + u32 first_cun : 8; + u32 : 24; + u32 last_cun : 8; + u32 : 32; + struct chsc_header response; + u8 data[PAGE_SIZE - 20]; + } __attribute__ ((packed)) *scucd_area; + + scucd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!scucd_area) + return -ENOMEM; + cd = kzalloc(sizeof(*cd), GFP_KERNEL); + if (!cd) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(cd, user_cd, sizeof(*cd))) { + ret = -EFAULT; + goto out_free; + } + scucd_area->request.length = 0x0010; + scucd_area->request.code = 0x0028; + scucd_area->m = cd->m; + scucd_area->fmt1 = cd->fmt; + scucd_area->cssid = cd->cssid; + scucd_area->first_cun = cd->cun; + scucd_area->last_cun = cd->cun; + + ccode = chsc(scucd_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (scucd_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "scucd: response code=%x\n", + scucd_area->response.code); + goto out_free; + } + memcpy(&cd->cucb, &scucd_area->response, scucd_area->response.length); + if (copy_to_user(user_cd, cd, sizeof(*cd))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(cd); + free_page((unsigned long)scucd_area); + return ret; +} + +static int chsc_ioctl_info_sch_cu(void __user *user_cud) +{ + struct chsc_sch_cud *cud; + int ret, ccode; + struct { + struct chsc_header request; + u32 : 2; + u32 m : 1; + u32 : 5; + u32 fmt1 : 4; + u32 : 2; + u32 ssid : 2; + u32 first_sch : 16; + u32 : 8; + u32 cssid : 8; + u32 last_sch : 16; + u32 : 32; + struct chsc_header response; + u8 data[PAGE_SIZE - 20]; + } __attribute__ ((packed)) *sscud_area; + + sscud_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sscud_area) + return -ENOMEM; + cud = kzalloc(sizeof(*cud), GFP_KERNEL); + if (!cud) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(cud, user_cud, sizeof(*cud))) { + ret = -EFAULT; + goto out_free; + } + sscud_area->request.length = 0x0010; + sscud_area->request.code = 0x0006; + sscud_area->m = cud->schid.m; + sscud_area->fmt1 = cud->fmt; + sscud_area->ssid = cud->schid.ssid; + sscud_area->first_sch = cud->schid.sch_no; + sscud_area->cssid = cud->schid.cssid; + sscud_area->last_sch = cud->schid.sch_no; + + ccode = chsc(sscud_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (sscud_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "sscud: response code=%x\n", + sscud_area->response.code); + goto out_free; + } + memcpy(&cud->scub, &sscud_area->response, sscud_area->response.length); + if (copy_to_user(user_cud, cud, sizeof(*cud))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(cud); + free_page((unsigned long)sscud_area); + return ret; +} + +static int chsc_ioctl_conf_info(void __user *user_ci) +{ + struct chsc_conf_info *ci; + int ret, ccode; + struct { + struct chsc_header request; + u32 : 2; + u32 m : 1; + u32 : 1; + u32 fmt1 : 4; + u32 cssid : 8; + u32 : 6; + u32 ssid : 2; + u32 : 8; + u64 : 64; + struct chsc_header response; + u8 data[PAGE_SIZE - 20]; + } __attribute__ ((packed)) *sci_area; + + sci_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sci_area) + return -ENOMEM; + ci = kzalloc(sizeof(*ci), GFP_KERNEL); + if (!ci) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(ci, user_ci, sizeof(*ci))) { + ret = -EFAULT; + goto out_free; + } + sci_area->request.length = 0x0010; + sci_area->request.code = 0x0012; + sci_area->m = ci->id.m; + sci_area->fmt1 = ci->fmt; + sci_area->cssid = ci->id.cssid; + sci_area->ssid = ci->id.ssid; + + ccode = chsc(sci_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (sci_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "sci: response code=%x\n", + sci_area->response.code); + goto out_free; + } + memcpy(&ci->scid, &sci_area->response, sci_area->response.length); + if (copy_to_user(user_ci, ci, sizeof(*ci))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(ci); + free_page((unsigned long)sci_area); + return ret; +} + +static int chsc_ioctl_conf_comp_list(void __user *user_ccl) +{ + struct chsc_comp_list *ccl; + int ret, ccode; + struct { + struct chsc_header request; + u32 ctype : 8; + u32 : 4; + u32 fmt : 4; + u32 : 16; + u64 : 64; + u32 list_parm[2]; + u64 : 64; + struct chsc_header response; + u8 data[PAGE_SIZE - 36]; + } __attribute__ ((packed)) *sccl_area; + struct { + u32 m : 1; + u32 : 31; + u32 cssid : 8; + u32 : 16; + u32 chpid : 8; + } __attribute__ ((packed)) *chpid_parm; + struct { + u32 f_cssid : 8; + u32 l_cssid : 8; + u32 : 16; + u32 res; + } __attribute__ ((packed)) *cssids_parm; + + sccl_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccl_area) + return -ENOMEM; + ccl = kzalloc(sizeof(*ccl), GFP_KERNEL); + if (!ccl) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(ccl, user_ccl, sizeof(*ccl))) { + ret = -EFAULT; + goto out_free; + } + sccl_area->request.length = 0x0020; + sccl_area->request.code = 0x0030; + sccl_area->fmt = ccl->req.fmt; + sccl_area->ctype = ccl->req.ctype; + switch (sccl_area->ctype) { + case CCL_CU_ON_CHP: + case CCL_IOP_CHP: + chpid_parm = (void *)&sccl_area->list_parm; + chpid_parm->m = ccl->req.chpid.m; + chpid_parm->cssid = ccl->req.chpid.chp.cssid; + chpid_parm->chpid = ccl->req.chpid.chp.id; + break; + case CCL_CSS_IMG: + case CCL_CSS_IMG_CONF_CHAR: + cssids_parm = (void *)&sccl_area->list_parm; + cssids_parm->f_cssid = ccl->req.cssids.f_cssid; + cssids_parm->l_cssid = ccl->req.cssids.l_cssid; + break; + } + ccode = chsc(sccl_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (sccl_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "sccl: response code=%x\n", + sccl_area->response.code); + goto out_free; + } + memcpy(&ccl->sccl, &sccl_area->response, sccl_area->response.length); + if (copy_to_user(user_ccl, ccl, sizeof(*ccl))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(ccl); + free_page((unsigned long)sccl_area); + return ret; +} + +static int chsc_ioctl_chpd(void __user *user_chpd) +{ + struct chsc_cpd_info *chpd; + int ret; + + chpd = kzalloc(sizeof(*chpd), GFP_KERNEL); + if (!chpd) + return -ENOMEM; + if (copy_from_user(chpd, user_chpd, sizeof(*chpd))) { + ret = -EFAULT; + goto out_free; + } + ret = chsc_determine_channel_path_desc(chpd->chpid, chpd->fmt, + chpd->rfmt, chpd->c, chpd->m, + &chpd->chpdb); + if (ret) + goto out_free; + if (copy_to_user(user_chpd, chpd, sizeof(*chpd))) + ret = -EFAULT; +out_free: + kfree(chpd); + return ret; +} + +static int chsc_ioctl_dcal(void __user *user_dcal) +{ + struct chsc_dcal *dcal; + int ret, ccode; + struct { + struct chsc_header request; + u32 atype : 8; + u32 : 4; + u32 fmt : 4; + u32 : 16; + u32 res0[2]; + u32 list_parm[2]; + u32 res1[2]; + struct chsc_header response; + u8 data[PAGE_SIZE - 36]; + } __attribute__ ((packed)) *sdcal_area; + + sdcal_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sdcal_area) + return -ENOMEM; + dcal = kzalloc(sizeof(*dcal), GFP_KERNEL); + if (!dcal) { + ret = -ENOMEM; + goto out_free; + } + if (copy_from_user(dcal, user_dcal, sizeof(*dcal))) { + ret = -EFAULT; + goto out_free; + } + sdcal_area->request.length = 0x0020; + sdcal_area->request.code = 0x0034; + sdcal_area->atype = dcal->req.atype; + sdcal_area->fmt = dcal->req.fmt; + memcpy(&sdcal_area->list_parm, &dcal->req.list_parm, + sizeof(sdcal_area->list_parm)); + + ccode = chsc(sdcal_area); + if (ccode != 0) { + ret = -EIO; + goto out_free; + } + if (sdcal_area->response.code != 0x0001) { + ret = -EIO; + CHSC_MSG(0, "sdcal: response code=%x\n", + sdcal_area->response.code); + goto out_free; + } + memcpy(&dcal->sdcal, &sdcal_area->response, + sdcal_area->response.length); + if (copy_to_user(user_dcal, dcal, sizeof(*dcal))) + ret = -EFAULT; + else + ret = 0; +out_free: + kfree(dcal); + free_page((unsigned long)sdcal_area); + return ret; +} + +static long chsc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); + switch (cmd) { + case CHSC_START: + return chsc_ioctl_start((void __user *)arg); + case CHSC_INFO_CHANNEL_PATH: + return chsc_ioctl_info_channel_path((void __user *)arg); + case CHSC_INFO_CU: + return chsc_ioctl_info_cu((void __user *)arg); + case CHSC_INFO_SCH_CU: + return chsc_ioctl_info_sch_cu((void __user *)arg); + case CHSC_INFO_CI: + return chsc_ioctl_conf_info((void __user *)arg); + case CHSC_INFO_CCL: + return chsc_ioctl_conf_comp_list((void __user *)arg); + case CHSC_INFO_CPD: + return chsc_ioctl_chpd((void __user *)arg); + case CHSC_INFO_DCAL: + return chsc_ioctl_dcal((void __user *)arg); + default: /* unknown ioctl number */ + return -ENOIOCTLCMD; + } +} + +static const struct file_operations chsc_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = chsc_ioctl, + .compat_ioctl = chsc_ioctl, +}; + +static struct miscdevice chsc_misc_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "chsc", + .fops = &chsc_fops, +}; + +static int __init chsc_misc_init(void) +{ + return misc_register(&chsc_misc_device); +} + +static void chsc_misc_cleanup(void) +{ + misc_deregister(&chsc_misc_device); +} + +static int __init chsc_sch_init(void) +{ + int ret; + + ret = chsc_init_dbfs(); + if (ret) + return ret; + isc_register(CHSC_SCH_ISC); + ret = chsc_init_sch_driver(); + if (ret) + goto out_dbf; + ret = chsc_misc_init(); + if (ret) + goto out_driver; + return ret; +out_driver: + chsc_cleanup_sch_driver(); +out_dbf: + isc_unregister(CHSC_SCH_ISC); + chsc_remove_dbfs(); + return ret; +} + +static void __exit chsc_sch_exit(void) +{ + chsc_misc_cleanup(); + chsc_cleanup_sch_driver(); + isc_unregister(CHSC_SCH_ISC); + chsc_remove_dbfs(); +} + +module_init(chsc_sch_init); +module_exit(chsc_sch_exit); diff --git a/drivers/s390/cio/chsc_sch.h b/drivers/s390/cio/chsc_sch.h new file mode 100644 index 00000000000..589ebfad6aa --- /dev/null +++ b/drivers/s390/cio/chsc_sch.h @@ -0,0 +1,13 @@ +#ifndef _CHSC_SCH_H +#define _CHSC_SCH_H + +struct chsc_request { + struct completion completion; + struct irb irb; +}; + +struct chsc_private { + struct chsc_request *request; +}; + +#endif diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 34b38fb7c2f..6ebf1b50736 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -877,6 +877,12 @@ __clear_io_subchannel_easy(struct subchannel_id schid) return -EBUSY; } +static void __clear_chsc_subchannel_easy(void) +{ + /* It seems we can only wait for a bit here :/ */ + udelay_reset(100); +} + static int pgm_check_occured; static void cio_reset_pgm_check_handler(void) @@ -920,6 +926,9 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) if (__clear_io_subchannel_easy(schid)) goto out; /* give up... */ break; + case SUBCHANNEL_TYPE_CHSC: + __clear_chsc_subchannel_easy(); + break; default: /* No default clear strategy */ break; diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 2e7e571d120..3b236d20e83 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -7,8 +7,8 @@ #include #include #include +#include #include "chsc.h" -#include "schid.h" /* * path management control word diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 58020bf41ed..57ebf120f82 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -9,8 +9,7 @@ #include #include - -#include "schid.h" +#include /* * path grouping stuff diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h index 144466ab8c1..528065cb502 100644 --- a/drivers/s390/cio/idset.h +++ b/drivers/s390/cio/idset.h @@ -8,7 +8,7 @@ #ifndef S390_IDSET_H #define S390_IDSET_H S390_IDSET_H -#include "schid.h" +#include struct idset; diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index b774960e76a..3f8f1cf69c7 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -1,7 +1,7 @@ #ifndef S390_IO_SCH_H #define S390_IO_SCH_H -#include "schid.h" +#include /* * command-mode operation request block diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 652ea3625f9..9fa2ac13ac8 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -2,7 +2,7 @@ #define S390_CIO_IOASM_H #include -#include "schid.h" +#include /* * TPI info structure diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 733934a166b..7656081a24d 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -3,8 +3,7 @@ #include #include - -#include "schid.h" +#include #ifdef CONFIG_QDIO_DEBUG #define QDIO_VERBOSE_LEVEL 9 diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild index 13c9805349f..09f312501eb 100644 --- a/include/asm-s390/Kbuild +++ b/include/asm-s390/Kbuild @@ -8,6 +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 diff --git a/include/asm-s390/chpid.h b/include/asm-s390/chpid.h index b203336fd89..606844d0a5c 100644 --- a/include/asm-s390/chpid.h +++ b/include/asm-s390/chpid.h @@ -10,7 +10,6 @@ #include #include -#include #define __MAX_CHPID 255 @@ -41,6 +40,9 @@ 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); @@ -49,5 +51,6 @@ static inline int chp_id_is_valid(struct chp_id *chpid) #define chp_id_for_each(c) \ for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c)) +#endif /* __KERNEL */ #endif /* _ASM_S390_CHPID_H */ diff --git a/include/asm-s390/chsc.h b/include/asm-s390/chsc.h new file mode 100644 index 00000000000..d38d0cf62d4 --- /dev/null +++ b/include/asm-s390/chsc.h @@ -0,0 +1,127 @@ +/* + * ioctl interface for /dev/chsc + * + * Copyright 2008 IBM Corp. + * Author(s): Cornelia Huck + */ + +#ifndef _ASM_CHSC_H +#define _ASM_CHSC_H + +#include +#include + +struct chsc_async_header { + __u16 length; + __u16 code; + __u32 cmd_dependend; + __u32 key : 4; + __u32 : 28; + struct subchannel_id sid; +} __attribute__ ((packed)); + +struct chsc_async_area { + struct chsc_async_header header; + __u8 data[PAGE_SIZE - 16 /* size of chsc_async_header */]; +} __attribute__ ((packed)); + + +struct chsc_response_struct { + __u16 length; + __u16 code; + __u32 parms; + __u8 data[PAGE_SIZE - 8]; +} __attribute__ ((packed)); + +struct chsc_chp_cd { + struct chp_id chpid; + int m; + int fmt; + struct chsc_response_struct cpcb; +}; + +struct chsc_cu_cd { + __u16 cun; + __u8 cssid; + int m; + int fmt; + struct chsc_response_struct cucb; +}; + +struct chsc_sch_cud { + struct subchannel_id schid; + int fmt; + struct chsc_response_struct scub; +}; + +struct conf_id { + int m; + __u8 cssid; + __u8 ssid; +}; + +struct chsc_conf_info { + struct conf_id id; + int fmt; + struct chsc_response_struct scid; +}; + +struct ccl_parm_chpid { + int m; + struct chp_id chp; +}; + +struct ccl_parm_cssids { + __u8 f_cssid; + __u8 l_cssid; +}; + +struct chsc_comp_list { + struct { + enum { + CCL_CU_ON_CHP = 1, + CCL_CHP_TYPE_CAP = 2, + CCL_CSS_IMG = 4, + CCL_CSS_IMG_CONF_CHAR = 5, + CCL_IOP_CHP = 6, + } ctype; + int fmt; + struct ccl_parm_chpid chpid; + struct ccl_parm_cssids cssids; + } req; + struct chsc_response_struct sccl; +}; + +struct chsc_dcal { + struct { + enum { + DCAL_CSS_IID_PN = 4, + } atype; + __u32 list_parm[2]; + int fmt; + } req; + struct chsc_response_struct sdcal; +}; + +struct chsc_cpd_info { + struct chp_id chpid; + int m; + int fmt; + int rfmt; + int c; + struct chsc_response_struct chpdb; +}; + +#define CHSC_IOCTL_MAGIC 'c' + +#define CHSC_START _IOWR(CHSC_IOCTL_MAGIC, 0x81, struct chsc_async_area) +#define CHSC_INFO_CHANNEL_PATH _IOWR(CHSC_IOCTL_MAGIC, 0x82, \ + struct chsc_chp_cd) +#define CHSC_INFO_CU _IOWR(CHSC_IOCTL_MAGIC, 0x83, struct chsc_cu_cd) +#define CHSC_INFO_SCH_CU _IOWR(CHSC_IOCTL_MAGIC, 0x84, struct chsc_sch_cud) +#define CHSC_INFO_CI _IOWR(CHSC_IOCTL_MAGIC, 0x85, struct chsc_conf_info) +#define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list) +#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) +#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) + +#endif diff --git a/include/asm-s390/isc.h b/include/asm-s390/isc.h index fe56f7b445e..34bb8916db4 100644 --- a/include/asm-s390/isc.h +++ b/include/asm-s390/isc.h @@ -14,6 +14,7 @@ /* Regular I/O interrupts. */ #define IO_SCH_ISC 3 /* regular I/O subchannels */ #define CONSOLE_ISC 1 /* console I/O subchannel */ +#define CHSC_SCH_ISC 7 /* CHSC subchannels */ /* Adapter interrupts. */ #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ diff --git a/drivers/s390/cio/schid.h b/include/asm-s390/schid.h similarity index 65% rename from drivers/s390/cio/schid.h rename to include/asm-s390/schid.h index 54328fec5ad..5017ffa78e0 100644 --- a/drivers/s390/cio/schid.h +++ b/include/asm-s390/schid.h @@ -1,12 +1,14 @@ -#ifndef S390_SCHID_H -#define S390_SCHID_H +#ifndef ASM_SCHID_H +#define ASM_SCHID_H struct subchannel_id { - __u32 reserved:13; - __u32 ssid:2; - __u32 one:1; - __u32 sch_no:16; -} __attribute__ ((packed,aligned(4))); + __u32 cssid : 8; + __u32 : 4; + __u32 m : 1; + __u32 ssid : 2; + __u32 one : 1; + __u32 sch_no : 16; +} __attribute__ ((packed, aligned(4))); /* Helper function for sane state of pre-allocated subchannel_id. */ @@ -23,4 +25,4 @@ schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2) return !memcmp(schid1, schid2, sizeof(struct subchannel_id)); } -#endif /* S390_SCHID_H */ +#endif /* ASM_SCHID_H */ -- GitLab From 773922e1dab93a62e60cfb34afadb0f66d5f12e9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:06 +0200 Subject: [PATCH 1773/2509] [S390] idle: remove idle notifier chain. The idle notifier chain consists of at most one element. So there's no point in having a notifier chain. Remove it and directly call the function. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/process.c | 32 ++------------------------------ arch/s390/kernel/vtime.c | 25 ++----------------------- include/asm-s390/processor.h | 10 ---------- include/asm-s390/timer.h | 12 ++++++++++++ 4 files changed, 16 insertions(+), 63 deletions(-) diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7920861109d..85defd01d29 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -75,46 +75,19 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return sf->gprs[8]; } -/* - * Need to know about CPUs going idle? - */ -static ATOMIC_NOTIFIER_HEAD(idle_chain); DEFINE_PER_CPU(struct s390_idle_data, s390_idle); -int register_idle_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&idle_chain, nb); -} -EXPORT_SYMBOL(register_idle_notifier); - -int unregister_idle_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&idle_chain, nb); -} -EXPORT_SYMBOL(unregister_idle_notifier); - static int s390_idle_enter(void) { struct s390_idle_data *idle; - int nr_calls = 0; - void *hcpu; - int rc; - hcpu = (void *)(long)smp_processor_id(); - rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1, - &nr_calls); - if (rc == NOTIFY_BAD) { - nr_calls--; - __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, - hcpu, nr_calls, NULL); - return rc; - } idle = &__get_cpu_var(s390_idle); spin_lock(&idle->lock); idle->idle_count++; idle->in_idle = 1; idle->idle_enter = get_clock(); spin_unlock(&idle->lock); + vtime_stop_cpu_timer(); return NOTIFY_OK; } @@ -122,13 +95,12 @@ void s390_idle_leave(void) { struct s390_idle_data *idle; + vtime_start_cpu_timer(); idle = &__get_cpu_var(s390_idle); spin_lock(&idle->lock); idle->idle_time += get_clock() - idle->idle_enter; idle->in_idle = 0; spin_unlock(&idle->lock); - atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, - (void *)(long) smp_processor_id()); } extern void s390_handle_mcck(void); diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index ca90ee3f930..eb08d04bc1e 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -136,7 +136,7 @@ static inline void set_vtimer(__u64 expires) } #endif -static void start_cpu_timer(void) +void vtime_start_cpu_timer(void) { struct vtimer_queue *vt_list; @@ -150,7 +150,7 @@ static void start_cpu_timer(void) set_vtimer(vt_list->idle); } -static void stop_cpu_timer(void) +void vtime_stop_cpu_timer(void) { struct vtimer_queue *vt_list; @@ -536,24 +536,6 @@ void init_cpu_vtimer(void) } -static int vtimer_idle_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - switch (action) { - case S390_CPU_IDLE: - stop_cpu_timer(); - break; - case S390_CPU_NOT_IDLE: - start_cpu_timer(); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block vtimer_idle_nb = { - .notifier_call = vtimer_idle_notify, -}; - void __init vtime_init(void) { /* request the cpu timer external interrupt */ @@ -561,9 +543,6 @@ void __init vtime_init(void) &ext_int_info_timer) != 0) panic("Couldn't request external interrupt 0x1005"); - if (register_idle_notifier(&vtimer_idle_nb)) - panic("Couldn't register idle notifier"); - /* Enable cpu timer interrupts on the boot cpu. */ init_cpu_vtimer(); } diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 5483c28b8bc..4af80af2a88 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -336,16 +336,6 @@ extern void (*s390_base_mcck_handler_fn)(void); extern void (*s390_base_pgm_handler_fn)(void); extern void (*s390_base_ext_handler_fn)(void); -/* - * CPU idle notifier chain. - */ -#define S390_CPU_IDLE 0 -#define S390_CPU_NOT_IDLE 1 - -struct notifier_block; -int register_idle_notifier(struct notifier_block *nb); -int unregister_idle_notifier(struct notifier_block *nb); - #define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL #endif diff --git a/include/asm-s390/timer.h b/include/asm-s390/timer.h index adb34860a54..d98d79e35cd 100644 --- a/include/asm-s390/timer.h +++ b/include/asm-s390/timer.h @@ -48,6 +48,18 @@ extern int del_virt_timer(struct vtimer_list *timer); extern void init_cpu_vtimer(void); extern void vtime_init(void); +#ifdef CONFIG_VIRT_TIMER + +extern void vtime_start_cpu_timer(void); +extern void vtime_stop_cpu_timer(void); + +#else + +static inline void vtime_start_cpu_timer(void) { } +static inline void vtime_stop_cpu_timer(void) { } + +#endif /* CONFIG_VIRT_TIMER */ + #endif /* __KERNEL__ */ #endif /* _ASM_S390_TIMER_H */ -- GitLab From ad211790c040fae3459e9c4c8cbd681ae126d2b8 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:59:07 +0200 Subject: [PATCH 1774/2509] [S390] sclp: simplify vt220 cleanup logic Fix a number of sclp_vt220 cleanup problems: * fix list_empty check after list_del() * mark init-only flag as __initdata * remove implicit dependency between slab_available() and num_pages * straighten multiple init handling (use init count) Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_vt220.c | 55 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 3e577f655b1..baea4d54852 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -82,8 +82,8 @@ static struct sclp_vt220_request *sclp_vt220_current_request; /* Number of characters in current request buffer */ static int sclp_vt220_buffered_chars; -/* Flag indicating whether this driver has already been initialized */ -static int sclp_vt220_initialized = 0; +/* Counter controlling core driver initialization. */ +static int __initdata sclp_vt220_init_count; /* Flag indicating that sclp_vt220_current_request should really * have been already queued but wasn't because the SCLP was processing @@ -609,10 +609,8 @@ sclp_vt220_flush_buffer(struct tty_struct *tty) sclp_vt220_emit_current(); } -/* - * Initialize all relevant components and register driver with system. - */ -static void __init __sclp_vt220_cleanup(void) +/* Release allocated pages. */ +static void __init __sclp_vt220_free_pages(void) { struct list_head *page, *p; @@ -623,21 +621,30 @@ static void __init __sclp_vt220_cleanup(void) else free_bootmem((unsigned long) page, PAGE_SIZE); } - if (!list_empty(&sclp_vt220_register.list)) - sclp_unregister(&sclp_vt220_register); - sclp_vt220_initialized = 0; } -static int __init __sclp_vt220_init(void) +/* Release memory and unregister from sclp core. Controlled by init counting - + * only the last invoker will actually perform these actions. */ +static void __init __sclp_vt220_cleanup(void) +{ + sclp_vt220_init_count--; + if (sclp_vt220_init_count != 0) + return; + sclp_unregister(&sclp_vt220_register); + __sclp_vt220_free_pages(); +} + +/* Allocate buffer pages and register with sclp core. Controlled by init + * counting - only the first invoker will actually perform these actions. */ +static int __init __sclp_vt220_init(int num_pages) { void *page; int i; - int num_pages; int rc; - if (sclp_vt220_initialized) + sclp_vt220_init_count++; + if (sclp_vt220_init_count != 1) return 0; - sclp_vt220_initialized = 1; spin_lock_init(&sclp_vt220_lock); INIT_LIST_HEAD(&sclp_vt220_empty); INIT_LIST_HEAD(&sclp_vt220_outqueue); @@ -649,24 +656,22 @@ static int __init __sclp_vt220_init(void) sclp_vt220_flush_later = 0; /* Allocate pages for output buffering */ - num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES; for (i = 0; i < num_pages; i++) { if (slab_is_available()) page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); else page = alloc_bootmem_low_pages(PAGE_SIZE); if (!page) { - __sclp_vt220_cleanup(); - return -ENOMEM; + rc = -ENOMEM; + goto out; } list_add_tail((struct list_head *) page, &sclp_vt220_empty); } rc = sclp_register(&sclp_vt220_register); +out: if (rc) { - printk(KERN_ERR SCLP_VT220_PRINT_HEADER - "could not register vt220 - " - "sclp_register returned %d\n", rc); - __sclp_vt220_cleanup(); + __sclp_vt220_free_pages(); + sclp_vt220_init_count--; } return rc; } @@ -689,15 +694,13 @@ static int __init sclp_vt220_tty_init(void) { struct tty_driver *driver; int rc; - int cleanup; /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve * symmetry between VM and LPAR systems regarding ttyS1. */ driver = alloc_tty_driver(1); if (!driver) return -ENOMEM; - cleanup = !sclp_vt220_initialized; - rc = __sclp_vt220_init(); + rc = __sclp_vt220_init(MAX_KMEM_PAGES); if (rc) goto out_driver; @@ -723,8 +726,7 @@ static int __init sclp_vt220_tty_init(void) return 0; out_init: - if (cleanup) - __sclp_vt220_cleanup(); + __sclp_vt220_cleanup(); out_driver: put_tty_driver(driver); return rc; @@ -773,10 +775,9 @@ sclp_vt220_con_init(void) { int rc; - INIT_LIST_HEAD(&sclp_vt220_register.list); if (!CONSOLE_IS_SCLP) return 0; - rc = __sclp_vt220_init(); + rc = __sclp_vt220_init(MAX_CONSOLE_PAGES); if (rc) return rc; /* Attach linux console */ -- GitLab From fe1372306149d8c8a68d43765e7caea2377003b6 Mon Sep 17 00:00:00 2001 From: Felix Beck Date: Mon, 14 Jul 2008 09:59:08 +0200 Subject: [PATCH 1775/2509] [S390] ap: Use high-resolution timer for polling The ap poll mechanism is converted to use a high-resolution timer for polling. This allows more specific polling. With this a new sysfs attribute is introduced to specify the polling rate in nanoseconds. Signed-off-by: Felix Beck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 63 ++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index a1ab3e3efd1..62b6b55230d 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -34,13 +34,15 @@ #include #include #include +#include +#include #include "ap_bus.h" /* Some prototypes. */ static void ap_scan_bus(struct work_struct *); static void ap_poll_all(unsigned long); -static void ap_poll_timeout(unsigned long); +static enum hrtimer_restart ap_poll_timeout(struct hrtimer *); static int ap_poll_thread_start(void); static void ap_poll_thread_stop(void); static void ap_request_timeout(unsigned long); @@ -80,12 +82,15 @@ static DECLARE_WORK(ap_config_work, ap_scan_bus); /* * Tasklet & timer for AP request polling. */ -static struct timer_list ap_poll_timer = TIMER_INITIALIZER(ap_poll_timeout,0,0); static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0); static atomic_t ap_poll_requests = ATOMIC_INIT(0); static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); static struct task_struct *ap_poll_kthread = NULL; static DEFINE_MUTEX(ap_poll_thread_mutex); +static struct hrtimer ap_poll_timer; +/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. + * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/ +static unsigned long long poll_timeout = 250000; /** * ap_intructions_available() - Test if AP instructions are available. @@ -636,11 +641,39 @@ static ssize_t ap_poll_thread_store(struct bus_type *bus, static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store); +static ssize_t poll_timeout_show(struct bus_type *bus, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout); +} + +static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, + size_t count) +{ + unsigned long long time; + ktime_t hr_time; + + /* 120 seconds = maximum poll interval */ + if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 || time > 120000000000) + return -EINVAL; + poll_timeout = time; + hr_time = ktime_set(0, poll_timeout); + + if (!hrtimer_is_queued(&ap_poll_timer) || + !hrtimer_forward(&ap_poll_timer, ap_poll_timer.expires, hr_time)) { + ap_poll_timer.expires = hr_time; + hrtimer_start(&ap_poll_timer, hr_time, HRTIMER_MODE_ABS); + } + return count; +} + +static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); + static struct bus_attribute *const ap_bus_attrs[] = { &bus_attr_ap_domain, &bus_attr_config_time, &bus_attr_poll_thread, - NULL + &bus_attr_poll_timeout, + NULL, }; /** @@ -895,9 +928,10 @@ ap_config_timeout(unsigned long ptr) */ static inline void ap_schedule_poll_timer(void) { - if (timer_pending(&ap_poll_timer)) + if (hrtimer_is_queued(&ap_poll_timer)) return; - mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME); + hrtimer_start(&ap_poll_timer, ktime_set(0, poll_timeout), + HRTIMER_MODE_ABS); } /** @@ -1115,13 +1149,14 @@ EXPORT_SYMBOL(ap_cancel_message); /** * ap_poll_timeout(): AP receive polling for finished AP requests. - * @unused: Unused variable. + * @unused: Unused pointer. * - * Schedules the AP tasklet. + * Schedules the AP tasklet using a high resolution timer. */ -static void ap_poll_timeout(unsigned long unused) +static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused) { tasklet_schedule(&ap_tasklet); + return HRTIMER_NORESTART; } /** @@ -1344,6 +1379,14 @@ int __init ap_module_init(void) ap_config_timer.expires = jiffies + ap_config_time * HZ; add_timer(&ap_config_timer); + /* Setup the high resultion poll timer. + * If we are running under z/VM adjust polling to z/VM polling rate. + */ + if (MACHINE_IS_VM) + poll_timeout = 1500000; + hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + ap_poll_timer.function = ap_poll_timeout; + /* Start the low priority AP bus poll thread. */ if (ap_thread_flag) { rc = ap_poll_thread_start(); @@ -1355,7 +1398,7 @@ int __init ap_module_init(void) out_work: del_timer_sync(&ap_config_timer); - del_timer_sync(&ap_poll_timer); + hrtimer_cancel(&ap_poll_timer); destroy_workqueue(ap_work_queue); out_root: s390_root_dev_unregister(ap_root_device); @@ -1386,7 +1429,7 @@ void ap_module_exit(void) ap_reset_domain(); ap_poll_thread_stop(); del_timer_sync(&ap_config_timer); - del_timer_sync(&ap_poll_timer); + hrtimer_cancel(&ap_poll_timer); destroy_workqueue(ap_work_queue); tasklet_kill(&ap_tasklet); s390_root_dev_unregister(ap_root_device); -- GitLab From a0443fbb467af5e5930b9b059b52190605f70059 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 14 Jul 2008 09:59:09 +0200 Subject: [PATCH 1776/2509] [S390] Extra Kernel Parameters via VMPARM Now it is possible to specify additional kernel parameters on the IPL command line using the IPL PARM option. If the Linux system is already running, the new reipl sysfs attribute 'parm' can be used to change kernel parameters for the next reboot. Examples: IPL C PARM dasd=1234 root=/dev/dasda1 IPL 1234 PARM savesys=mylnxnss echo "init=/bin/bash" > /sys/firmware/reipl/ccw/parm Signed-off-by: Hendrik Brueckner Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/early.c | 80 ++++++- arch/s390/kernel/ipl.c | 444 +++++++++++++++++++++++++++++++++------ arch/s390/kernel/setup.c | 17 +- include/asm-s390/ipl.h | 17 +- include/asm-s390/setup.h | 4 +- 5 files changed, 475 insertions(+), 87 deletions(-) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index b2226e41f06..e22473993dc 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -26,12 +27,40 @@ /* * Create a Kernel NSS if the SAVESYS= parameter is defined */ -#define DEFSYS_CMD_SIZE 96 +#define DEFSYS_CMD_SIZE 128 #define SAVESYS_CMD_SIZE 32 char kernel_nss_name[NSS_NAME_SIZE + 1]; +static void __init setup_boot_command_line(void); + + #ifdef CONFIG_SHARED_KERNEL +int __init savesys_ipl_nss(char *cmd, const int cmdlen); + +asm( + " .section .init.text,\"ax\",@progbits\n" + " .align 4\n" + " .type savesys_ipl_nss, @function\n" + "savesys_ipl_nss:\n" +#ifdef CONFIG_64BIT + " stmg 6,15,48(15)\n" + " lgr 14,3\n" + " sam31\n" + " diag 2,14,0x8\n" + " sam64\n" + " lgr 2,14\n" + " lmg 6,15,48(15)\n" +#else + " stm 6,15,24(15)\n" + " lr 14,3\n" + " diag 2,14,0x8\n" + " lr 2,14\n" + " lm 6,15,24(15)\n" +#endif + " br 14\n" + " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); + static noinline __init void create_kernel_nss(void) { unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; @@ -39,6 +68,7 @@ static noinline __init void create_kernel_nss(void) unsigned int sinitrd_pfn, einitrd_pfn; #endif int response; + size_t len; char *savesys_ptr; char upper_command_line[COMMAND_LINE_SIZE]; char defsys_cmd[DEFSYS_CMD_SIZE]; @@ -49,8 +79,8 @@ static noinline __init void create_kernel_nss(void) return; /* Convert COMMAND_LINE to upper case */ - for (i = 0; i < strlen(COMMAND_LINE); i++) - upper_command_line[i] = toupper(COMMAND_LINE[i]); + for (i = 0; i < strlen(boot_command_line); i++) + upper_command_line[i] = toupper(boot_command_line[i]); savesys_ptr = strstr(upper_command_line, "SAVESYS="); @@ -83,7 +113,8 @@ static noinline __init void create_kernel_nss(void) } #endif - sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size); + sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13", + defsys_cmd, min_size); sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", kernel_nss_name, kernel_nss_name); @@ -94,13 +125,24 @@ static noinline __init void create_kernel_nss(void) return; } - __cpcmd(savesys_cmd, NULL, 0, &response); + len = strlen(savesys_cmd); + ASCEBC(savesys_cmd, len); + response = savesys_ipl_nss(savesys_cmd, len); - if (response != strlen(savesys_cmd)) { + /* On success: response is equal to the command size, + * max SAVESYS_CMD_SIZE + * On error: response contains the numeric portion of cp error message. + * for SAVESYS it will be >= 263 + */ + if (response > SAVESYS_CMD_SIZE) { kernel_nss_name[0] = '\0'; return; } + /* re-setup boot command line with new ipl vm parms */ + ipl_update_parameters(); + setup_boot_command_line(); + ipl_flags = IPL_NSS_VALID; } @@ -397,6 +439,26 @@ static __init void rescue_initrd(void) #endif } +/* Set up boot command line */ +static void __init setup_boot_command_line(void) +{ + char *parm = NULL; + + /* copy arch command line */ + strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); + boot_command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0; + + /* append IPL PARM data to the boot command line */ + if (MACHINE_IS_VM) { + parm = boot_command_line + strlen(boot_command_line); + *parm++ = ' '; + get_ipl_vmparm(parm); + if (parm[0] == '=') + memmove(boot_command_line, parm + 1, strlen(parm)); + } +} + + /* * Save ipl parameters, clear bss memory, initialize storage keys * and create a kernel NSS at startup if the SAVESYS= parm is defined @@ -411,10 +473,12 @@ void __init startup_init(void) init_kernel_storage_key(); lockdep_init(); lockdep_off(); - detect_machine_type(); - create_kernel_nss(); sort_main_extable(); setup_lowcore_early(); + detect_machine_type(); + ipl_update_parameters(); + setup_boot_command_line(); + create_kernel_nss(); detect_mvpg(); detect_ieee(); detect_csp(); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 532542447d6..9f6dfd306ab 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -22,6 +22,7 @@ #include #include #include +#include #define IPL_PARM_BLOCK_VERSION 0 @@ -121,6 +122,7 @@ enum ipl_method { REIPL_METHOD_FCP_RO_VM, REIPL_METHOD_FCP_DUMP, REIPL_METHOD_NSS, + REIPL_METHOD_NSS_DIAG, REIPL_METHOD_DEFAULT, }; @@ -134,14 +136,15 @@ enum dump_method { static int diag308_set_works = 0; +static struct ipl_parameter_block ipl_block; + static int reipl_capabilities = IPL_TYPE_UNKNOWN; static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT; static struct ipl_parameter_block *reipl_block_fcp; static struct ipl_parameter_block *reipl_block_ccw; - -static char reipl_nss_name[NSS_NAME_SIZE + 1]; +static struct ipl_parameter_block *reipl_block_nss; static int dump_capabilities = DUMP_TYPE_NONE; static enum dump_type dump_type = DUMP_TYPE_NONE; @@ -263,6 +266,56 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); +/* VM IPL PARM routines */ +static void reipl_get_ascii_vmparm(char *dest, + const struct ipl_parameter_block *ipb) +{ + int i; + int len = 0; + char has_lowercase = 0; + + if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && + (ipb->ipl_info.ccw.vm_parm_len > 0)) { + + len = ipb->ipl_info.ccw.vm_parm_len; + memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); + /* If at least one character is lowercase, we assume mixed + * case; otherwise we convert everything to lowercase. + */ + for (i = 0; i < len; i++) + if ((dest[i] > 0x80 && dest[i] < 0x8a) || /* a-i */ + (dest[i] > 0x90 && dest[i] < 0x9a) || /* j-r */ + (dest[i] > 0xa1 && dest[i] < 0xaa)) { /* s-z */ + has_lowercase = 1; + break; + } + if (!has_lowercase) + EBC_TOLOWER(dest, len); + EBCASC(dest, len); + } + dest[len] = 0; +} + +void get_ipl_vmparm(char *dest) +{ + if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) + reipl_get_ascii_vmparm(dest, &ipl_block); + else + dest[0] = 0; +} + +static ssize_t ipl_vm_parm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + char parm[DIAG308_VMPARM_SIZE + 1] = {}; + + get_ipl_vmparm(parm); + return sprintf(page, "%s\n", parm); +} + +static struct kobj_attribute sys_ipl_vm_parm_attr = + __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); + static ssize_t sys_ipl_device_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { @@ -370,15 +423,27 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, static struct kobj_attribute sys_ipl_ccw_loadparm_attr = __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL); -static struct attribute *ipl_ccw_attrs[] = { +static struct attribute *ipl_ccw_attrs_vm[] = { + &sys_ipl_type_attr.attr, + &sys_ipl_device_attr.attr, + &sys_ipl_ccw_loadparm_attr.attr, + &sys_ipl_vm_parm_attr.attr, + NULL, +}; + +static struct attribute *ipl_ccw_attrs_lpar[] = { &sys_ipl_type_attr.attr, &sys_ipl_device_attr.attr, &sys_ipl_ccw_loadparm_attr.attr, NULL, }; -static struct attribute_group ipl_ccw_attr_group = { - .attrs = ipl_ccw_attrs, +static struct attribute_group ipl_ccw_attr_group_vm = { + .attrs = ipl_ccw_attrs_vm, +}; + +static struct attribute_group ipl_ccw_attr_group_lpar = { + .attrs = ipl_ccw_attrs_lpar }; /* NSS ipl device attributes */ @@ -388,6 +453,8 @@ DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name); static struct attribute *ipl_nss_attrs[] = { &sys_ipl_type_attr.attr, &sys_ipl_nss_name_attr.attr, + &sys_ipl_ccw_loadparm_attr.attr, + &sys_ipl_vm_parm_attr.attr, NULL, }; @@ -450,7 +517,12 @@ static int __init ipl_init(void) } switch (ipl_info.type) { case IPL_TYPE_CCW: - rc = sysfs_create_group(&ipl_kset->kobj, &ipl_ccw_attr_group); + if (MACHINE_IS_VM) + rc = sysfs_create_group(&ipl_kset->kobj, + &ipl_ccw_attr_group_vm); + else + rc = sysfs_create_group(&ipl_kset->kobj, + &ipl_ccw_attr_group_lpar); break; case IPL_TYPE_FCP: case IPL_TYPE_FCP_DUMP: @@ -481,6 +553,83 @@ static struct shutdown_action __refdata ipl_action = { * reipl shutdown action: Reboot Linux on shutdown. */ +/* VM IPL PARM attributes */ +static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, + char *page) +{ + char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; + + reipl_get_ascii_vmparm(vmparm, ipb); + return sprintf(page, "%s\n", vmparm); +} + +static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb, + size_t vmparm_max, + const char *buf, size_t len) +{ + int i, ip_len; + + /* ignore trailing newline */ + ip_len = len; + if ((len > 0) && (buf[len - 1] == '\n')) + ip_len--; + + if (ip_len > vmparm_max) + return -EINVAL; + + /* parm is used to store kernel options, check for common chars */ + for (i = 0; i < ip_len; i++) + if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i]))) + return -EINVAL; + + memset(ipb->ipl_info.ccw.vm_parm, 0, DIAG308_VMPARM_SIZE); + ipb->ipl_info.ccw.vm_parm_len = ip_len; + if (ip_len > 0) { + ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID; + memcpy(ipb->ipl_info.ccw.vm_parm, buf, ip_len); + ASCEBC(ipb->ipl_info.ccw.vm_parm, ip_len); + } else { + ipb->ipl_info.ccw.vm_flags &= ~DIAG308_VM_FLAGS_VP_VALID; + } + + return len; +} + +/* NSS wrapper */ +static ssize_t reipl_nss_vmparm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return reipl_generic_vmparm_show(reipl_block_nss, page); +} + +static ssize_t reipl_nss_vmparm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len); +} + +/* CCW wrapper */ +static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return reipl_generic_vmparm_show(reipl_block_ccw, page); +} + +static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len); +} + +static struct kobj_attribute sys_reipl_nss_vmparm_attr = + __ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show, + reipl_nss_vmparm_store); +static struct kobj_attribute sys_reipl_ccw_vmparm_attr = + __ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show, + reipl_ccw_vmparm_store); + /* FCP reipl device attributes */ DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", @@ -513,27 +662,26 @@ static struct attribute_group reipl_fcp_attr_group = { DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", reipl_block_ccw->ipl_info.ccw.devno); -static void reipl_get_ascii_loadparm(char *loadparm) +static void reipl_get_ascii_loadparm(char *loadparm, + struct ipl_parameter_block *ibp) { - memcpy(loadparm, &reipl_block_ccw->ipl_info.ccw.load_param, - LOADPARM_LEN); + memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN); EBCASC(loadparm, LOADPARM_LEN); loadparm[LOADPARM_LEN] = 0; strstrip(loadparm); } -static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj, - struct kobj_attribute *attr, char *page) +static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb, + char *page) { char buf[LOADPARM_LEN + 1]; - reipl_get_ascii_loadparm(buf); + reipl_get_ascii_loadparm(buf, ipb); return sprintf(page, "%s\n", buf); } -static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t len) +static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb, + const char *buf, size_t len) { int i, lp_len; @@ -552,35 +700,128 @@ static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj, return -EINVAL; } /* initialize loadparm with blanks */ - memset(&reipl_block_ccw->ipl_info.ccw.load_param, ' ', LOADPARM_LEN); + memset(ipb->ipl_info.ccw.load_parm, ' ', LOADPARM_LEN); /* copy and convert to ebcdic */ - memcpy(&reipl_block_ccw->ipl_info.ccw.load_param, buf, lp_len); - ASCEBC(reipl_block_ccw->ipl_info.ccw.load_param, LOADPARM_LEN); + memcpy(ipb->ipl_info.ccw.load_parm, buf, lp_len); + ASCEBC(ipb->ipl_info.ccw.load_parm, LOADPARM_LEN); return len; } +/* NSS wrapper */ +static ssize_t reipl_nss_loadparm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return reipl_generic_loadparm_show(reipl_block_nss, page); +} + +static ssize_t reipl_nss_loadparm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return reipl_generic_loadparm_store(reipl_block_nss, buf, len); +} + +/* CCW wrapper */ +static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return reipl_generic_loadparm_show(reipl_block_ccw, page); +} + +static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return reipl_generic_loadparm_store(reipl_block_ccw, buf, len); +} + static struct kobj_attribute sys_reipl_ccw_loadparm_attr = - __ATTR(loadparm, 0644, reipl_ccw_loadparm_show, - reipl_ccw_loadparm_store); + __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show, + reipl_ccw_loadparm_store); + +static struct attribute *reipl_ccw_attrs_vm[] = { + &sys_reipl_ccw_device_attr.attr, + &sys_reipl_ccw_loadparm_attr.attr, + &sys_reipl_ccw_vmparm_attr.attr, + NULL, +}; -static struct attribute *reipl_ccw_attrs[] = { +static struct attribute *reipl_ccw_attrs_lpar[] = { &sys_reipl_ccw_device_attr.attr, &sys_reipl_ccw_loadparm_attr.attr, NULL, }; -static struct attribute_group reipl_ccw_attr_group = { +static struct attribute_group reipl_ccw_attr_group_vm = { .name = IPL_CCW_STR, - .attrs = reipl_ccw_attrs, + .attrs = reipl_ccw_attrs_vm, +}; + +static struct attribute_group reipl_ccw_attr_group_lpar = { + .name = IPL_CCW_STR, + .attrs = reipl_ccw_attrs_lpar, }; /* NSS reipl device attributes */ +static void reipl_get_ascii_nss_name(char *dst, + struct ipl_parameter_block *ipb) +{ + memcpy(dst, ipb->ipl_info.ccw.nss_name, NSS_NAME_SIZE); + EBCASC(dst, NSS_NAME_SIZE); + dst[NSS_NAME_SIZE] = 0; +} + +static ssize_t reipl_nss_name_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + char nss_name[NSS_NAME_SIZE + 1] = {}; + + reipl_get_ascii_nss_name(nss_name, reipl_block_nss); + return sprintf(page, "%s\n", nss_name); +} + +static ssize_t reipl_nss_name_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + int nss_len; + + /* ignore trailing newline */ + nss_len = len; + if ((len > 0) && (buf[len - 1] == '\n')) + nss_len--; -DEFINE_IPL_ATTR_STR_RW(reipl_nss, name, "%s\n", "%s\n", reipl_nss_name); + if (nss_len > NSS_NAME_SIZE) + return -EINVAL; + + memset(reipl_block_nss->ipl_info.ccw.nss_name, 0x40, NSS_NAME_SIZE); + if (nss_len > 0) { + reipl_block_nss->ipl_info.ccw.vm_flags |= + DIAG308_VM_FLAGS_NSS_VALID; + memcpy(reipl_block_nss->ipl_info.ccw.nss_name, buf, nss_len); + ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, nss_len); + EBC_TOUPPER(reipl_block_nss->ipl_info.ccw.nss_name, nss_len); + } else { + reipl_block_nss->ipl_info.ccw.vm_flags &= + ~DIAG308_VM_FLAGS_NSS_VALID; + } + + return len; +} + +static struct kobj_attribute sys_reipl_nss_name_attr = + __ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show, + reipl_nss_name_store); + +static struct kobj_attribute sys_reipl_nss_loadparm_attr = + __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show, + reipl_nss_loadparm_store); static struct attribute *reipl_nss_attrs[] = { &sys_reipl_nss_name_attr.attr, + &sys_reipl_nss_loadparm_attr.attr, + &sys_reipl_nss_vmparm_attr.attr, NULL, }; @@ -617,7 +858,10 @@ static int reipl_set_type(enum ipl_type type) reipl_method = REIPL_METHOD_FCP_DUMP; break; case IPL_TYPE_NSS: - reipl_method = REIPL_METHOD_NSS; + if (diag308_set_works) + reipl_method = REIPL_METHOD_NSS_DIAG; + else + reipl_method = REIPL_METHOD_NSS; break; case IPL_TYPE_UNKNOWN: reipl_method = REIPL_METHOD_DEFAULT; @@ -655,11 +899,38 @@ static struct kobj_attribute reipl_type_attr = static struct kset *reipl_kset; +static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, + const enum ipl_method m) +{ + char loadparm[LOADPARM_LEN + 1] = {}; + char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; + char nss_name[NSS_NAME_SIZE + 1] = {}; + size_t pos = 0; + + reipl_get_ascii_loadparm(loadparm, ipb); + reipl_get_ascii_nss_name(nss_name, ipb); + reipl_get_ascii_vmparm(vmparm, ipb); + + switch (m) { + case REIPL_METHOD_CCW_VM: + pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno); + break; + case REIPL_METHOD_NSS: + pos = sprintf(dst, "IPL %s", nss_name); + break; + default: + break; + } + if (strlen(loadparm) > 0) + pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm); + if (strlen(vmparm) > 0) + sprintf(dst + pos, " PARM %s", vmparm); +} + static void reipl_run(struct shutdown_trigger *trigger) { struct ccw_dev_id devid; - static char buf[100]; - char loadparm[LOADPARM_LEN + 1]; + static char buf[128]; switch (reipl_method) { case REIPL_METHOD_CCW_CIO: @@ -668,13 +939,7 @@ static void reipl_run(struct shutdown_trigger *trigger) reipl_ccw_dev(&devid); break; case REIPL_METHOD_CCW_VM: - reipl_get_ascii_loadparm(loadparm); - if (strlen(loadparm) == 0) - sprintf(buf, "IPL %X CLEAR", - reipl_block_ccw->ipl_info.ccw.devno); - else - sprintf(buf, "IPL %X CLEAR LOADPARM '%s'", - reipl_block_ccw->ipl_info.ccw.devno, loadparm); + get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM); __cpcmd(buf, NULL, 0, NULL); break; case REIPL_METHOD_CCW_DIAG: @@ -691,8 +956,12 @@ static void reipl_run(struct shutdown_trigger *trigger) case REIPL_METHOD_FCP_RO_VM: __cpcmd("IPL", NULL, 0, NULL); break; + case REIPL_METHOD_NSS_DIAG: + diag308(DIAG308_SET, reipl_block_nss); + diag308(DIAG308_IPL, NULL); + break; case REIPL_METHOD_NSS: - sprintf(buf, "IPL %s", reipl_nss_name); + get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS); __cpcmd(buf, NULL, 0, NULL); break; case REIPL_METHOD_DEFAULT: @@ -707,16 +976,36 @@ static void reipl_run(struct shutdown_trigger *trigger) disabled_wait((unsigned long) __builtin_return_address(0)); } -static void __init reipl_probe(void) +static void reipl_block_ccw_init(struct ipl_parameter_block *ipb) { - void *buffer; + ipb->hdr.len = IPL_PARM_BLK_CCW_LEN; + ipb->hdr.version = IPL_PARM_BLOCK_VERSION; + ipb->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; + ipb->hdr.pbt = DIAG308_IPL_TYPE_CCW; +} - buffer = (void *) get_zeroed_page(GFP_KERNEL); - if (!buffer) - return; - if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK) - diag308_set_works = 1; - free_page((unsigned long)buffer); +static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb) +{ + /* LOADPARM */ + /* check if read scp info worked and set loadparm */ + if (sclp_ipl_info.is_valid) + memcpy(ipb->ipl_info.ccw.load_parm, + &sclp_ipl_info.loadparm, LOADPARM_LEN); + else + /* read scp info failed: set empty loadparm (EBCDIC blanks) */ + memset(ipb->ipl_info.ccw.load_parm, 0x40, LOADPARM_LEN); + ipb->hdr.flags = DIAG308_FLAGS_LP_VALID; + + /* VM PARM */ + if (MACHINE_IS_VM && diag308_set_works && + (ipl_block.ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID)) { + + ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID; + ipb->ipl_info.ccw.vm_parm_len = + ipl_block.ipl_info.ccw.vm_parm_len; + memcpy(ipb->ipl_info.ccw.vm_parm, + ipl_block.ipl_info.ccw.vm_parm, DIAG308_VMPARM_SIZE); + } } static int __init reipl_nss_init(void) @@ -725,10 +1014,31 @@ static int __init reipl_nss_init(void) if (!MACHINE_IS_VM) return 0; + + reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL); + if (!reipl_block_nss) + return -ENOMEM; + + if (!diag308_set_works) + sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO; + rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group); if (rc) return rc; - strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1); + + reipl_block_ccw_init(reipl_block_nss); + if (ipl_info.type == IPL_TYPE_NSS) { + memset(reipl_block_nss->ipl_info.ccw.nss_name, + ' ', NSS_NAME_SIZE); + memcpy(reipl_block_nss->ipl_info.ccw.nss_name, + kernel_nss_name, strlen(kernel_nss_name)); + ASCEBC(reipl_block_nss->ipl_info.ccw.nss_name, NSS_NAME_SIZE); + reipl_block_nss->ipl_info.ccw.vm_flags |= + DIAG308_VM_FLAGS_NSS_VALID; + + reipl_block_ccw_fill_parms(reipl_block_nss); + } + reipl_capabilities |= IPL_TYPE_NSS; return 0; } @@ -740,28 +1050,27 @@ static int __init reipl_ccw_init(void) reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL); if (!reipl_block_ccw) return -ENOMEM; - rc = sysfs_create_group(&reipl_kset->kobj, &reipl_ccw_attr_group); - if (rc) { - free_page((unsigned long)reipl_block_ccw); - return rc; + + if (MACHINE_IS_VM) { + if (!diag308_set_works) + sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO; + rc = sysfs_create_group(&reipl_kset->kobj, + &reipl_ccw_attr_group_vm); + } else { + if(!diag308_set_works) + sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; + rc = sysfs_create_group(&reipl_kset->kobj, + &reipl_ccw_attr_group_lpar); } - reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; - reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; - reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; - reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; - reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID; - /* check if read scp info worked and set loadparm */ - if (sclp_ipl_info.is_valid) - memcpy(reipl_block_ccw->ipl_info.ccw.load_param, - &sclp_ipl_info.loadparm, LOADPARM_LEN); - else - /* read scp info failed: set empty loadparm (EBCDIC blanks) */ - memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, - LOADPARM_LEN); - if (!MACHINE_IS_VM && !diag308_set_works) - sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; - if (ipl_info.type == IPL_TYPE_CCW) + if (rc) + return rc; + + reipl_block_ccw_init(reipl_block_ccw); + if (ipl_info.type == IPL_TYPE_CCW) { reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; + reipl_block_ccw_fill_parms(reipl_block_ccw); + } + reipl_capabilities |= IPL_TYPE_CCW; return 0; } @@ -1298,7 +1607,6 @@ static void __init shutdown_actions_init(void) static int __init s390_ipl_init(void) { - reipl_probe(); sclp_get_ipl_info(&sclp_ipl_info); shutdown_actions_init(); shutdown_triggers_init(); @@ -1405,6 +1713,12 @@ void __init setup_ipl(void) atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); } +void __init ipl_update_parameters(void) +{ + if (diag308(DIAG308_STORE, &ipl_block) == DIAG308_RC_OK) + diag308_set_works = 1; +} + void __init ipl_save_parameters(void) { struct cio_iplinfo iplinfo; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b91caadf974..e3b4cdbae34 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -221,18 +221,17 @@ static void __init conmode_default(void) #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) static void __init setup_zfcpdump(unsigned int console_devno) { - static char str[64]; + static char str[41]; if (ipl_info.type != IPL_TYPE_FCP_DUMP) return; if (console_devno != -1) - sprintf(str, "cio_ignore=all,!0.0.%04x,!0.0.%04x", + sprintf(str, " cio_ignore=all,!0.0.%04x,!0.0.%04x", ipl_info.data.fcp.dev_id.devno, console_devno); else - sprintf(str, "cio_ignore=all,!0.0.%04x", + sprintf(str, " cio_ignore=all,!0.0.%04x", ipl_info.data.fcp.dev_id.devno); - strcat(COMMAND_LINE, " "); - strcat(COMMAND_LINE, str); + strcat(boot_command_line, str); console_loglevel = 2; } #else @@ -778,11 +777,9 @@ setup_arch(char **cmdline_p) printk("We are running native (64 bit mode)\n"); #endif /* CONFIG_64BIT */ - /* Save unparsed command line copy for /proc/cmdline */ - strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - - *cmdline_p = COMMAND_LINE; - *(*cmdline_p + COMMAND_LINE_SIZE - 1) = '\0'; + /* Have one command line that is parsed and saved in /proc/cmdline */ + /* boot_command_line has been already set up in early.c */ + *cmdline_p = boot_command_line; ROOT_DEV = Root_RAM0; diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h index c1b2e50392b..eaca6dff540 100644 --- a/include/asm-s390/ipl.h +++ b/include/asm-s390/ipl.h @@ -56,15 +56,19 @@ struct ipl_block_fcp { u8 scp_data[]; } __attribute__((packed)); +#define DIAG308_VMPARM_SIZE 64 + struct ipl_block_ccw { - u8 load_param[8]; + u8 load_parm[8]; u8 reserved1[84]; u8 reserved2[2]; u16 devno; u8 vm_flags; u8 reserved3[3]; u32 vm_parm_len; - u8 reserved4[80]; + u8 nss_name[8]; + u8 vm_parm[DIAG308_VMPARM_SIZE]; + u8 reserved4[8]; } __attribute__((packed)); struct ipl_parameter_block { @@ -73,7 +77,7 @@ struct ipl_parameter_block { struct ipl_block_fcp fcp; struct ipl_block_ccw ccw; } ipl_info; -} __attribute__((packed)); +} __attribute__((packed,aligned(4096))); /* * IPL validity flags @@ -86,6 +90,8 @@ extern void do_reipl(void); extern void do_halt(void); extern void do_poff(void); extern void ipl_save_parameters(void); +extern void ipl_update_parameters(void); +extern void get_ipl_vmparm(char *); enum { IPL_DEVNO_VALID = 1, @@ -147,6 +153,11 @@ enum diag308_flags { DIAG308_FLAGS_LP_VALID = 0x80, }; +enum diag308_vm_flags { + DIAG308_VM_FLAGS_NSS_VALID = 0x80, + DIAG308_VM_FLAGS_VP_VALID = 0x40, +}; + enum diag308_rc { DIAG308_RC_OK = 1, }; diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index ba69674012a..f5eebc48d98 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -8,7 +8,9 @@ #ifndef _ASM_S390_SETUP_H #define _ASM_S390_SETUP_H -#define COMMAND_LINE_SIZE 896 +#define COMMAND_LINE_SIZE 1024 + +#define ARCH_COMMAND_LINE_SIZE 896 #ifdef __KERNEL__ -- GitLab From d8c33d32a4c4f326579e7c2960492512de74662b Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Mon, 14 Jul 2008 09:59:10 +0200 Subject: [PATCH 1777/2509] [S390] zcrypt: Add additional card IDs to CEX2C and CEX2A Add support for new micro code load of CEX2C and CEX2A adapters, which uses different IDs. This patch just adds the IDs to the existing drivers. Signed-off-by: Ralph Wuerthner Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.h | 2 ++ drivers/s390/crypto/zcrypt_cex2a.c | 1 + drivers/s390/crypto/zcrypt_pcixcc.c | 1 + include/asm-s390/zcrypt.h | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index c1e1200c43f..446378b308f 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -92,6 +92,8 @@ struct ap_queue_status { #define AP_DEVICE_TYPE_PCIXCC 5 #define AP_DEVICE_TYPE_CEX2A 6 #define AP_DEVICE_TYPE_CEX2C 7 +#define AP_DEVICE_TYPE_CEX2A2 8 +#define AP_DEVICE_TYPE_CEX2C2 9 /* * AP reset flag states diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 08657f604b8..78ffba1dd61 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c @@ -49,6 +49,7 @@ static struct ap_device_id zcrypt_cex2a_ids[] = { { AP_DEVICE(AP_DEVICE_TYPE_CEX2A) }, + { AP_DEVICE(AP_DEVICE_TYPE_CEX2A2) }, { /* end of list */ }, }; diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 0bc9b3188e6..4040c1c981d 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c @@ -72,6 +72,7 @@ struct response_type { static struct ap_device_id zcrypt_pcixcc_ids[] = { { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) }, { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) }, + { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) }, { /* end of list */ }, }; diff --git a/include/asm-s390/zcrypt.h b/include/asm-s390/zcrypt.h index f228f1b8687..00d3bbd4411 100644 --- a/include/asm-s390/zcrypt.h +++ b/include/asm-s390/zcrypt.h @@ -29,7 +29,7 @@ #define ZCRYPT_VERSION 2 #define ZCRYPT_RELEASE 1 -#define ZCRYPT_VARIANT 0 +#define ZCRYPT_VARIANT 1 #include #include -- GitLab From 9789db08c020193ae18826c3aa48bd24296f7848 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:11 +0200 Subject: [PATCH 1778/2509] [S390] Add sched.h include to asm-s390/pgtable.h. Some macros in pgtable.h access members from struct task_struct. Currently always works since sched.h seems always to be included before asm/pgtable.h. Unfortunately that is not anymore true with Jeremy Fitzhardinge's ptep_modify_prot transaction abstraction patch. So fix this. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- include/asm-s390/pgtable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index bd0ea191dfa..0bdb704ae05 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -29,6 +29,7 @@ * the S390 page table tree. */ #ifndef __ASSEMBLY__ +#include #include #include #include -- GitLab From 402a3998ba6ba81bae6ac586ada55a0dd6a7c287 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Jul 2008 09:59:12 +0200 Subject: [PATCH 1779/2509] [S390] arch/s390: Eliminate NULL test and memset after alloc_bootmem As noted by Akinobu Mita in patch b1fceac2b9e04d278316b2faddf276015fc06e3b, alloc_bootmem and related functions never return NULL and always return a zeroed region of memory. Thus a NULL test or memset after calls to these functions is unnecessary. arch/s390/kernel/topology.c | 2 -- 1 file changed, 2 deletions(-) This was fixed using the following semantic patch. (http://www.emn.fr/x-info/coccinelle/) // @@ expression E; statement S; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) ... when != E ( - BUG_ON (E == NULL); | - if (E == NULL) S ) @@ expression E,E1; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) ... when != E - memset(E,0,E1); // Signed-off-by: Julia Lawall Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/topology.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 661a0721705..212d618b009 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -313,8 +313,6 @@ void __init s390_init_cpu_topology(void) machine_has_topology_irq = 1; tl_info = alloc_bootmem_pages(PAGE_SIZE); - if (!tl_info) - goto error; info = tl_info; stsi(info, 15, 1, 2); -- GitLab From 3ca1c9907a352140bc83366511182b6ac776d8ee Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Jul 2008 09:59:13 +0200 Subject: [PATCH 1780/2509] [S390] drivers/s390: Eliminate NULL test and memset after alloc_bootmem As noted by Akinobu Mita in patch b1fceac2b9e04d278316b2faddf276015fc06e3b, alloc_bootmem and related functions never return NULL and always return a zeroed region of memory. Thus a NULL test or memset after calls to these functions is unnecessary. drivers/s390/char/raw3270.c | 11 +---------- drivers/s390/char/sclp_con.c | 2 -- 2 files changed, 1 insertion(+), 12 deletions(-) This was fixed using the following semantic patch. (http://www.emn.fr/x-info/coccinelle/) // @@ expression E; statement S; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) ... when != E ( - BUG_ON (E == NULL); | - if (E == NULL) S ) @@ expression E,E1; @@ E = \(alloc_bootmem\|alloc_bootmem_low\|alloc_bootmem_pages\|alloc_bootmem_low_pages\)(...) ... when != E - memset(E,0,E1); // Signed-off-by: Julia Lawall Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/raw3270.c | 11 +---------- drivers/s390/char/sclp_con.c | 2 -- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index efce32e97be..e2767e3b8cf 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -153,19 +153,10 @@ struct raw3270_request __init *raw3270_request_alloc_bootmem(size_t size) struct raw3270_request *rq; rq = alloc_bootmem_low(sizeof(struct raw3270)); - if (!rq) - return ERR_PTR(-ENOMEM); - memset(rq, 0, sizeof(struct raw3270_request)); /* alloc output buffer. */ - if (size > 0) { + if (size > 0) rq->buffer = alloc_bootmem_low(size); - if (!rq->buffer) { - free_bootmem((unsigned long) rq, - sizeof(struct raw3270)); - return ERR_PTR(-ENOMEM); - } - } rq->size = size; INIT_LIST_HEAD(&rq->list); diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c index ead1043d788..23bb90a5ed2 100644 --- a/drivers/s390/char/sclp_con.c +++ b/drivers/s390/char/sclp_con.c @@ -222,8 +222,6 @@ sclp_console_init(void) INIT_LIST_HEAD(&sclp_con_pages); for (i = 0; i < MAX_CONSOLE_PAGES; i++) { page = alloc_bootmem_low_pages(PAGE_SIZE); - if (page == NULL) - return -ENOMEM; list_add_tail((struct list_head *) page, &sclp_con_pages); } INIT_LIST_HEAD(&sclp_con_outqueue); -- GitLab From 7785857a5a4f3e2093ced12568744a205e164d59 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 14 Jul 2008 09:59:14 +0200 Subject: [PATCH 1781/2509] [S390] s390/vmcp: use simple_read_from_buffer() Signed-off-by: Akinobu Mita Cc: Christian Borntraeger Signed-off-by: Andrew Morton Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmcp.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 2f419b0ea62..af616aeaa93 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -61,30 +61,24 @@ static int vmcp_release(struct inode *inode, struct file *file) static ssize_t vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { - size_t tocopy; + ssize_t ret; + size_t size; struct vmcp_session *session; - session = (struct vmcp_session *)file->private_data; + session = file->private_data; if (mutex_lock_interruptible(&session->mutex)) return -ERESTARTSYS; if (!session->response) { mutex_unlock(&session->mutex); return 0; } - if (*ppos > session->resp_size) { - mutex_unlock(&session->mutex); - return 0; - } - tocopy = min(session->resp_size - (size_t) (*ppos), count); - tocopy = min(tocopy, session->bufsize - (size_t) (*ppos)); + size = min_t(size_t, session->resp_size, session->bufsize); + ret = simple_read_from_buffer(buff, count, ppos, + session->response, size); - if (copy_to_user(buff, session->response + (*ppos), tocopy)) { - mutex_unlock(&session->mutex); - return -EFAULT; - } mutex_unlock(&session->mutex); - *ppos += tocopy; - return tocopy; + + return ret; } static ssize_t -- GitLab From d9cef21af03eb56473db5bb20d8754f377a498e7 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 14 Jul 2008 09:59:15 +0200 Subject: [PATCH 1782/2509] [S390] s390/cio: use memory_read_from_buffer() Signed-off-by: Akinobu Mita Cc: Peter Oberparleiter Signed-off-by: Andrew Morton Signed-off-by Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chp.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 8644c80a205..d58dc9f15b7 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -143,21 +143,14 @@ static ssize_t chp_measurement_chars_read(struct kobject *kobj, { struct channel_path *chp; struct device *device; - unsigned int size; device = container_of(kobj, struct device, kobj); chp = to_channelpath(device); if (!chp->cmg_chars) return 0; - size = sizeof(struct cmg_chars); - - if (off > size) - return 0; - if (off + count > size) - count = size - off; - memcpy(buf, chp->cmg_chars + off, count); - return count; + return memory_read_from_buffer(buf, count, &off, + chp->cmg_chars, sizeof(struct cmg_chars)); } static struct bin_attribute chp_measurement_chars_attr = { -- GitLab From a29591c47524dde594c84a279a5f1827e688a4c4 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 14 Jul 2008 09:59:16 +0200 Subject: [PATCH 1783/2509] [S390] s390: use simple_read_from_buffer() Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/hypfs/inode.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 4b010ff814c..7383781f3e6 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -150,33 +150,24 @@ static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t offset) { char *data; - size_t len; + ssize_t ret; struct file *filp = iocb->ki_filp; /* XXX: temporary */ char __user *buf = iov[0].iov_base; size_t count = iov[0].iov_len; - if (nr_segs != 1) { - count = -EINVAL; - goto out; - } + if (nr_segs != 1) + return -EINVAL; data = filp->private_data; - len = strlen(data); - if (offset > len) { - count = 0; - goto out; - } - if (count > len - offset) - count = len - offset; - if (copy_to_user(buf, data + offset, count)) { - count = -EFAULT; - goto out; - } - iocb->ki_pos += count; + ret = simple_read_from_buffer(buf, count, &offset, data, strlen(data)); + if (ret <= 0) + return ret; + + iocb->ki_pos += ret; file_accessed(filp); -out: - return count; + + return ret; } static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t offset) -- GitLab From 0788fea4d583a3b7d199696819940ff3387d79a3 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 14 Jul 2008 09:59:17 +0200 Subject: [PATCH 1784/2509] [S390] s390: use memory_read_from_buffer() Signed-off-by: Akinobu Mita Cc: Michael Holzheu Signed-off-by: Andrew Morton Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 9f6dfd306ab..54b2779b5e2 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -338,14 +339,8 @@ static struct kobj_attribute sys_ipl_device_attr = static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - unsigned int size = IPL_PARMBLOCK_SIZE; - - if (off > size) - return 0; - if (off + count > size) - count = size - off; - memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count); - return count; + return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START, + IPL_PARMBLOCK_SIZE); } static struct bin_attribute ipl_parameter_attr = { @@ -363,12 +358,7 @@ static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *att unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; - if (off > size) - return 0; - if (off + count > size) - count = size - off; - memcpy(buf, scp_data + off, count); - return count; + return memory_read_from_buffer(buf, count, &off, scp_data, size); } static struct bin_attribute ipl_scp_data_attr = { -- GitLab From 421c175c4d609864350df495b34d3e99f9fb1bdd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:18 +0200 Subject: [PATCH 1785/2509] [S390] Add support for memory hot-add. Cc: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 4 ++++ arch/s390/mm/init.c | 19 +++++++++++++++++++ include/asm-s390/sparsemem.h | 4 ++-- mm/Kconfig | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 6d0d31651f0..5dc8f8028d5 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -313,6 +313,10 @@ config ARCH_SPARSEMEM_DEFAULT config ARCH_SELECT_MEMORY_MODEL def_bool y +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on SPARSEMEM + source "mm/Kconfig" comment "I/O subsystem configuration" diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 05598649b32..388cc742005 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -202,3 +202,22 @@ void free_initrd_mem(unsigned long start, unsigned long end) } } #endif + +#ifdef CONFIG_MEMORY_HOTPLUG +int arch_add_memory(int nid, u64 start, u64 size) +{ + struct pglist_data *pgdat; + struct zone *zone; + int rc; + + pgdat = NODE_DATA(nid); + zone = pgdat->node_zones + ZONE_NORMAL; + rc = vmem_add_mapping(start, size); + if (rc) + return rc; + rc = __add_pages(zone, PFN_DOWN(start), PFN_DOWN(size)); + if (rc) + vmem_remove_mapping(start, size); + return rc; +} +#endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/include/asm-s390/sparsemem.h b/include/asm-s390/sparsemem.h index 06dfdab6c0e..545d219e6a2 100644 --- a/include/asm-s390/sparsemem.h +++ b/include/asm-s390/sparsemem.h @@ -1,15 +1,15 @@ #ifndef _ASM_S390_SPARSEMEM_H #define _ASM_S390_SPARSEMEM_H -#define SECTION_SIZE_BITS 25 - #ifdef CONFIG_64BIT +#define SECTION_SIZE_BITS 28 #define MAX_PHYSADDR_BITS 42 #define MAX_PHYSMEM_BITS 42 #else +#define SECTION_SIZE_BITS 25 #define MAX_PHYSADDR_BITS 31 #define MAX_PHYSMEM_BITS 31 diff --git a/mm/Kconfig b/mm/Kconfig index 3aa819d628c..4242743b981 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -129,7 +129,7 @@ config MEMORY_HOTPLUG bool "Allow for memory hot-add" depends on SPARSEMEM || X86_64_ACPI_NUMA depends on HOTPLUG && !HIBERNATION && ARCH_ENABLE_MEMORY_HOTPLUG - depends on (IA64 || X86 || PPC64 || SUPERH) + depends on (IA64 || X86 || PPC64 || SUPERH || S390) comment "Memory hotplug is currently incompatible with Software Suspend" depends on SPARSEMEM && HOTPLUG && HIBERNATION -- GitLab From e0bc24958e1305efe176adc9d5f23a09e84c0058 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:19 +0200 Subject: [PATCH 1786/2509] [S390] Add support for memory hot-add via sclp. Cc: Peter Oberparleiter Cc: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_cmd.c | 316 ++++++++++++++++++++++++++++++++++- 1 file changed, 308 insertions(+), 8 deletions(-) diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index b5c23396f8f..4f45884c92c 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include #include "sclp.h" @@ -43,6 +46,8 @@ static int __initdata early_read_info_sccb_valid; u64 sclp_facilities; static u8 sclp_fac84; +static unsigned long long rzm; +static unsigned long long rnmax; static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) { @@ -106,14 +111,10 @@ unsigned long long __init sclp_memory_detect(void) if (!early_read_info_sccb_valid) return 0; sccb = &early_read_info_sccb; - if (sccb->rnsize) - memsize = sccb->rnsize << 20; - else - memsize = sccb->rnsize2 << 20; - if (sccb->rnmax) - memsize *= sccb->rnmax; - else - memsize *= sccb->rnmax2; + rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; + rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; + rzm <<= 20; + memsize = rzm * rnmax; return memsize; } @@ -278,6 +279,305 @@ int sclp_cpu_deconfigure(u8 cpu) return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU | cpu << 8); } +#ifdef CONFIG_MEMORY_HOTPLUG + +static DEFINE_MUTEX(sclp_mem_mutex); +static LIST_HEAD(sclp_mem_list); +static u8 sclp_max_storage_id; +static unsigned long sclp_storage_ids[256 / BITS_PER_LONG]; + +struct memory_increment { + struct list_head list; + u16 rn; + int standby; + int usecount; +}; + +struct assign_storage_sccb { + struct sccb_header header; + u16 rn; +} __packed; + +static unsigned long long rn2addr(u16 rn) +{ + return (unsigned long long) (rn - 1) * rzm; +} + +static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) +{ + struct assign_storage_sccb *sccb; + int rc; + + sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + return -ENOMEM; + sccb->header.length = PAGE_SIZE; + sccb->rn = rn; + rc = do_sync_request(cmd, sccb); + if (rc) + goto out; + switch (sccb->header.response_code) { + case 0x0020: + case 0x0120: + break; + default: + rc = -EIO; + break; + } +out: + free_page((unsigned long) sccb); + return rc; +} + +static int sclp_assign_storage(u16 rn) +{ + return do_assign_storage(0x000d0001, rn); +} + +static int sclp_unassign_storage(u16 rn) +{ + return do_assign_storage(0x000c0001, rn); +} + +struct attach_storage_sccb { + struct sccb_header header; + u16 :16; + u16 assigned; + u32 :32; + u32 entries[0]; +} __packed; + +static int sclp_attach_storage(u8 id) +{ + struct attach_storage_sccb *sccb; + int rc; + int i; + + sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + return -ENOMEM; + sccb->header.length = PAGE_SIZE; + rc = do_sync_request(0x00080001 | id << 8, sccb); + if (rc) + goto out; + switch (sccb->header.response_code) { + case 0x0020: + set_bit(id, sclp_storage_ids); + for (i = 0; i < sccb->assigned; i++) + sclp_unassign_storage(sccb->entries[i] >> 16); + break; + default: + rc = -EIO; + break; + } +out: + free_page((unsigned long) sccb); + return rc; +} + +static int sclp_mem_change_state(unsigned long start, unsigned long size, + int online) +{ + struct memory_increment *incr; + unsigned long long istart; + int rc = 0; + + list_for_each_entry(incr, &sclp_mem_list, list) { + istart = rn2addr(incr->rn); + if (start + size - 1 < istart) + break; + if (start > istart + rzm - 1) + continue; + if (online) { + if (incr->usecount++) + continue; + /* + * Don't break the loop if one assign fails. Loop may + * be walked again on CANCEL and we can't save + * information if state changed before or not. + * So continue and increase usecount for all increments. + */ + rc |= sclp_assign_storage(incr->rn); + } else { + if (--incr->usecount) + continue; + sclp_unassign_storage(incr->rn); + } + } + return rc ? -EIO : 0; +} + +static int sclp_mem_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + unsigned long start, size; + struct memory_notify *arg; + unsigned char id; + int rc = 0; + + arg = data; + start = arg->start_pfn << PAGE_SHIFT; + size = arg->nr_pages << PAGE_SHIFT; + mutex_lock(&sclp_mem_mutex); + for (id = 0; id <= sclp_max_storage_id; id++) + if (!test_bit(id, sclp_storage_ids)) + sclp_attach_storage(id); + switch (action) { + case MEM_ONLINE: + break; + case MEM_GOING_ONLINE: + rc = sclp_mem_change_state(start, size, 1); + break; + case MEM_CANCEL_ONLINE: + sclp_mem_change_state(start, size, 0); + break; + default: + rc = -EINVAL; + break; + } + mutex_unlock(&sclp_mem_mutex); + return rc ? NOTIFY_BAD : NOTIFY_OK; +} + +static struct notifier_block sclp_mem_nb = { + .notifier_call = sclp_mem_notifier, +}; + +static void __init add_memory_merged(u16 rn) +{ + static u16 first_rn, num; + unsigned long long start, size; + + if (rn && first_rn && (first_rn + num == rn)) { + num++; + return; + } + if (!first_rn) + goto skip_add; + start = rn2addr(first_rn); + size = (unsigned long long ) num * rzm; + if (start >= VMEM_MAX_PHYS) + goto skip_add; + if (start + size > VMEM_MAX_PHYS) + size = VMEM_MAX_PHYS - start; + add_memory(0, start, size); +skip_add: + first_rn = rn; + num = 1; +} + +static void __init sclp_add_standby_memory(void) +{ + struct memory_increment *incr; + + list_for_each_entry(incr, &sclp_mem_list, list) + if (incr->standby) + add_memory_merged(incr->rn); + add_memory_merged(0); +} + +static void __init insert_increment(u16 rn, int standby, int assigned) +{ + struct memory_increment *incr, *new_incr; + struct list_head *prev; + u16 last_rn; + + new_incr = kzalloc(sizeof(*new_incr), GFP_KERNEL); + if (!new_incr) + return; + new_incr->rn = rn; + new_incr->standby = standby; + last_rn = 0; + prev = &sclp_mem_list; + list_for_each_entry(incr, &sclp_mem_list, list) { + if (assigned && incr->rn > rn) + break; + if (!assigned && incr->rn - last_rn > 1) + break; + last_rn = incr->rn; + prev = &incr->list; + } + if (!assigned) + new_incr->rn = last_rn + 1; + if (new_incr->rn > rnmax) { + kfree(new_incr); + return; + } + list_add(&new_incr->list, prev); +} + +struct read_storage_sccb { + struct sccb_header header; + u16 max_id; + u16 assigned; + u16 standby; + u16 :16; + u32 entries[0]; +} __packed; + +static int __init sclp_detect_standby_memory(void) +{ + struct read_storage_sccb *sccb; + int i, id, assigned, rc; + + if (!early_read_info_sccb_valid) + return 0; + if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) + return 0; + rc = -ENOMEM; + sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + goto out; + assigned = 0; + for (id = 0; id <= sclp_max_storage_id; id++) { + memset(sccb, 0, PAGE_SIZE); + sccb->header.length = PAGE_SIZE; + rc = do_sync_request(0x00040001 | id << 8, sccb); + if (rc) + goto out; + switch (sccb->header.response_code) { + case 0x0010: + set_bit(id, sclp_storage_ids); + for (i = 0; i < sccb->assigned; i++) { + if (!sccb->entries[i]) + continue; + assigned++; + insert_increment(sccb->entries[i] >> 16, 0, 1); + } + break; + case 0x0310: + break; + case 0x0410: + for (i = 0; i < sccb->assigned; i++) { + if (!sccb->entries[i]) + continue; + assigned++; + insert_increment(sccb->entries[i] >> 16, 1, 1); + } + break; + default: + rc = -EIO; + break; + } + if (!rc) + sclp_max_storage_id = sccb->max_id; + } + if (rc || list_empty(&sclp_mem_list)) + goto out; + for (i = 1; i <= rnmax - assigned; i++) + insert_increment(0, 1, 0); + rc = register_memory_notifier(&sclp_mem_nb); + if (rc) + goto out; + sclp_add_standby_memory(); +out: + free_page((unsigned long) sccb); + return rc; +} +__initcall(sclp_detect_standby_memory); + +#endif /* CONFIG_MEMORY_HOTPLUG */ + /* * Channel path configuration related functions. */ -- GitLab From ef60cd13ecee0ccf2439d63013cbfc798aea2bb9 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 14 Jul 2008 09:59:20 +0200 Subject: [PATCH 1787/2509] [S390] cio: fix double unregistering of subchannels In some cases where the channel subsystem decides to drop a subchannel device device_unregister may be called twice, which results in an oops. The patch prevents this by only unregistering registered devices. Signed-off-by: Sebastian Ott Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 4e2f2bbf4ba..46c021d880d 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -164,7 +164,8 @@ static int css_sch_device_register(struct subchannel *sch) void css_sch_device_unregister(struct subchannel *sch) { mutex_lock(&sch->reg_mutex); - device_unregister(&sch->dev); + if (device_is_registered(&sch->dev)) + device_unregister(&sch->dev); mutex_unlock(&sch->reg_mutex); } EXPORT_SYMBOL_GPL(css_sch_device_unregister); -- GitLab From 23d1742179170b69e61ac9166248ffd64857e55a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:21 +0200 Subject: [PATCH 1788/2509] [S390] Move memory detection code to own file. Move memory detection code to own file and also simplify it. Also add an interface which can be called at any time to get the current memory layout. This interface is needed by our kernel internal system dumper. Cc: Peter Oberparleiter Cc: Michael Holzheu Cc: Frank Munzert Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/early.c | 109 +--------------------------------- arch/s390/kernel/mem_detect.c | 100 +++++++++++++++++++++++++++++++ arch/s390/kernel/setup.c | 2 +- drivers/s390/char/sclp_cmd.c | 33 +++++----- include/asm-s390/sclp.h | 4 +- include/asm-s390/setup.h | 6 +- 7 files changed, 127 insertions(+), 129 deletions(-) create mode 100644 arch/s390/kernel/mem_detect.c diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 0fed81d91e0..50f657e7734 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -14,7 +14,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - s390_ext.o debug.o irq.o ipl.o dis.o diag.o + s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index e22473993dc..4c0ec7b46e3 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -192,100 +192,6 @@ static noinline __init void detect_machine_type(void) machine_flags |= MACHINE_FLAG_KVM; } -#ifdef CONFIG_64BIT -static noinline __init int memory_fast_detect(void) -{ - unsigned long val0 = 0; - unsigned long val1 = 0xc; - int ret = -ENOSYS; - - if (ipl_flags & IPL_NSS_VALID) - return -ENOSYS; - - asm volatile( - " diag %1,%2,0x260\n" - "0: lhi %0,0\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (ret), "+d" (val0), "+d" (val1) : : "cc"); - - if (ret || val0 != val1) - return -ENOSYS; - - memory_chunk[0].size = val0 + 1; - return 0; -} -#else -static inline int memory_fast_detect(void) -{ - return -ENOSYS; -} -#endif - -static inline __init unsigned long __tprot(unsigned long addr) -{ - int cc = -1; - - asm volatile( - " tprot 0(%1),0\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (cc) : "a" (addr) : "cc"); - return (unsigned long)cc; -} - -/* Checking memory in 128KB increments. */ -#define CHUNK_INCR (1UL << 17) -#define ADDR2G (1UL << 31) - -static noinline __init void find_memory_chunks(unsigned long memsize) -{ - unsigned long addr = 0, old_addr = 0; - unsigned long old_cc = CHUNK_READ_WRITE; - unsigned long cc; - int chunk = 0; - - while (chunk < MEMORY_CHUNKS) { - cc = __tprot(addr); - while (cc == old_cc) { - addr += CHUNK_INCR; - if (memsize && addr >= memsize) - break; -#ifndef CONFIG_64BIT - if (addr == ADDR2G) - break; -#endif - cc = __tprot(addr); - } - - if (old_addr != addr && - (old_cc == CHUNK_READ_WRITE || old_cc == CHUNK_READ_ONLY)) { - memory_chunk[chunk].addr = old_addr; - memory_chunk[chunk].size = addr - old_addr; - memory_chunk[chunk].type = old_cc; - chunk++; - } - - old_addr = addr; - old_cc = cc; - -#ifndef CONFIG_64BIT - if (addr == ADDR2G) - break; -#endif - /* - * Finish memory detection at the first hole - * if storage size is unknown. - */ - if (cc == -1UL && !memsize) - break; - if (memsize && addr >= memsize) - break; - } -} - static __init void early_pgm_check_handler(void) { unsigned long addr; @@ -465,8 +371,6 @@ static void __init setup_boot_command_line(void) */ void __init startup_init(void) { - unsigned long long memsize; - ipl_save_parameters(); rescue_initrd(); clear_bss_section(); @@ -486,18 +390,7 @@ void __init startup_init(void) detect_diag44(); detect_machine_facilities(); setup_hpage(); - sclp_read_info_early(); sclp_facilities_detect(); - memsize = sclp_memory_detect(); -#ifndef CONFIG_64BIT - /* - * Can't deal with more than 2G in 31 bit addressing mode, so - * limit the value in order to avoid strange side effects. - */ - if (memsize > ADDR2G) - memsize = ADDR2G; -#endif - if (memory_fast_detect() < 0) - find_memory_chunks((unsigned long) memsize); + detect_memory_layout(memory_chunk); lockdep_on(); } diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c new file mode 100644 index 00000000000..18ed7abe16c --- /dev/null +++ b/arch/s390/kernel/mem_detect.c @@ -0,0 +1,100 @@ +/* + * Copyright IBM Corp. 2008 + * Author(s): Heiko Carstens + */ + +#include +#include +#include +#include +#include + +static int memory_fast_detect(struct mem_chunk *chunk) +{ + unsigned long val0 = 0; + unsigned long val1 = 0xc; + int rc = -EOPNOTSUPP; + + if (ipl_flags & IPL_NSS_VALID) + return -EOPNOTSUPP; + asm volatile( + " diag %1,%2,0x260\n" + "0: lhi %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "+d" (rc), "+d" (val0), "+d" (val1) : : "cc"); + + if (rc || val0 != val1) + return -EOPNOTSUPP; + chunk->size = val0 + 1; + return 0; +} + +static inline int tprot(unsigned long addr) +{ + int rc = -EFAULT; + + asm volatile( + " tprot 0(%1),0\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b,1b) + : "+d" (rc) : "a" (addr) : "cc"); + return rc; +} + +#define ADDR2G (1ULL << 31) + +static void find_memory_chunks(struct mem_chunk chunk[]) +{ + unsigned long long memsize, rnmax, rzm; + unsigned long addr = 0, size; + int i = 0, type; + + rzm = sclp_get_rzm(); + rnmax = sclp_get_rnmax(); + memsize = rzm * rnmax; + if (!rzm) + rzm = 1ULL << 17; + if (sizeof(long) == 4) { + rzm = min(ADDR2G, rzm); + memsize = memsize ? min(ADDR2G, memsize) : ADDR2G; + } + do { + size = 0; + type = tprot(addr); + do { + size += rzm; + if (memsize && addr + size >= memsize) + break; + } while (type == tprot(addr + size)); + if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { + chunk[i].addr = addr; + chunk[i].size = size; + chunk[i].type = type; + i++; + } + addr += size; + } while (addr < memsize && i < MEMORY_CHUNKS); +} + +void detect_memory_layout(struct mem_chunk chunk[]) +{ + unsigned long flags, cr0; + + memset(chunk, 0, MEMORY_CHUNKS * sizeof(struct mem_chunk)); + if (memory_fast_detect(&chunk[0]) == 0) + return; + /* Disable IRQs, DAT and low address protection so tprot does the + * right thing and we don't get scheduled away with low address + * protection disabled. + */ + flags = __raw_local_irq_stnsm(0xf8); + __ctl_store(cr0, 0, 0); + __ctl_clear_bit(0, 28); + find_memory_chunks(chunk); + __ctl_load(cr0, 0, 0); + __raw_local_irq_ssm(flags); +} +EXPORT_SYMBOL(detect_memory_layout); diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e3b4cdbae34..9c92407f625 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -77,7 +77,7 @@ unsigned long machine_flags; unsigned long elf_hwcap = 0; char elf_platform[ELF_PLATFORM_SIZE]; -struct mem_chunk __meminitdata memory_chunk[MEMORY_CHUNKS]; +struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ static unsigned long __initdata memory_end; diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 4f45884c92c..0c2b77493db 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -67,7 +67,7 @@ out: return rc; } -void __init sclp_read_info_early(void) +static void __init sclp_read_info_early(void) { int rc; int i; @@ -97,30 +97,33 @@ void __init sclp_read_info_early(void) void __init sclp_facilities_detect(void) { - if (!early_read_info_sccb_valid) - return; - sclp_facilities = early_read_info_sccb.facilities; - sclp_fac84 = early_read_info_sccb.fac84; -} - -unsigned long long __init sclp_memory_detect(void) -{ - unsigned long long memsize; struct read_info_sccb *sccb; + sclp_read_info_early(); if (!early_read_info_sccb_valid) - return 0; + return; + sccb = &early_read_info_sccb; + sclp_facilities = sccb->facilities; + sclp_fac84 = sccb->fac84; rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; rzm <<= 20; - memsize = rzm * rnmax; - return memsize; +} + +unsigned long long sclp_get_rnmax(void) +{ + return rnmax; +} + +unsigned long long sclp_get_rzm(void) +{ + return rzm; } /* - * This function will be called after sclp_memory_detect(), which gets called - * early from early.c code. Therefore the sccb should have valid contents. + * This function will be called after sclp_facilities_detect(), which gets + * called from early.c code. Therefore the sccb should have valid contents. */ void __init sclp_get_ipl_info(struct sclp_ipl_info *info) { diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index b5f2843013a..fed7bee650a 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h @@ -45,9 +45,9 @@ struct sclp_cpu_info { int sclp_get_cpu_info(struct sclp_cpu_info *info); int sclp_cpu_configure(u8 cpu); int sclp_cpu_deconfigure(u8 cpu); -void sclp_read_info_early(void); void sclp_facilities_detect(void); -unsigned long long sclp_memory_detect(void); +unsigned long long sclp_get_rnmax(void); +unsigned long long sclp_get_rzm(void); int sclp_sdias_blk_count(void); int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); int sclp_chp_configure(struct chp_id chpid); diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index f5eebc48d98..80747ba6ef8 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -17,7 +17,7 @@ #include #define PARMAREA 0x10400 -#define MEMORY_CHUNKS 16 /* max 0x7fff */ +#define MEMORY_CHUNKS 256 #ifndef __ASSEMBLY__ @@ -38,12 +38,14 @@ struct mem_chunk { unsigned long addr; unsigned long size; - unsigned long type; + int type; }; extern struct mem_chunk memory_chunk[]; extern unsigned long real_memory_size; +void detect_memory_layout(struct mem_chunk chunk[]); + #ifdef CONFIG_S390_SWITCH_AMODE extern unsigned int switch_amode; #else -- GitLab From c78aa6cbace460081ddc6227f02b6d3203a21585 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Mon, 14 Jul 2008 09:59:22 +0200 Subject: [PATCH 1789/2509] [S390] Cleanup cio printk messages. Unnecessary dev_info, dev_warn and printk messages are removed. Signed-off-by: Michael Ernst Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/chp.c | 7 ++----- drivers/s390/cio/cio.c | 3 +-- drivers/s390/cio/cmf.c | 9 --------- drivers/s390/cio/device.c | 18 ++++++++---------- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index d58dc9f15b7..db00b059173 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -123,11 +123,8 @@ static int s390_vary_chpid(struct chp_id chpid, int on) CIO_TRACE_EVENT(2, dbf_text); status = chp_get_status(chpid); - if (!on && !status) { - printk(KERN_ERR "cio: chpid %x.%02x is already offline\n", - chpid.cssid, chpid.id); - return -EINVAL; - } + if (!on && !status) + return 0; set_chp_logically_online(chpid, on); chsc_chp_vary(chpid, on); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 6ebf1b50736..33bff8fec7d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -74,7 +74,6 @@ out_unregister: debug_unregister(cio_debug_trace_id); if (cio_debug_crw_id) debug_unregister(cio_debug_crw_id); - printk(KERN_WARNING"cio: could not initialize debugging\n"); return -1; } @@ -755,7 +754,6 @@ cio_get_console_sch_no(void) /* unlike in 2.4, we cannot autoprobe here, since * the channel subsystem is not fully initialized. * With some luck, the HWC console can take over */ - printk(KERN_WARNING "cio: No ccw console found!\n"); return -1; } return console_irq; @@ -772,6 +770,7 @@ cio_probe_console(void) sch_no = cio_get_console_sch_no(); if (sch_no == -1) { console_subchannel_in_use = 0; + printk(KERN_WARNING "cio: No ccw console found!\n"); return ERR_PTR(-ENODEV); } memset(&console_subchannel, 0, sizeof(struct subchannel)); diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 77523131a05..a90b28c0be5 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -612,9 +612,6 @@ static int alloc_cmb(struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ - printk(KERN_WARNING "cio: failed to allocate area " - "for measuring %d subchannels\n", - cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1230,13 +1227,9 @@ static ssize_t cmb_enable_store(struct device *dev, switch (val) { case 0: ret = disable_cmf(cdev); - if (ret) - dev_info(&cdev->dev, "disable_cmf failed (%d)\n", ret); break; case 1: ret = enable_cmf(cdev); - if (ret && ret != -EBUSY) - dev_info(&cdev->dev, "enable_cmf failed (%d)\n", ret); break; } @@ -1364,8 +1357,6 @@ static int __init init_cmf(void) cmbops = &cmbops_extended; break; default: - printk(KERN_ERR "cio: Invalid format %d for channel " - "measurement facility\n", format); return 1; } diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index c904cb84d75..e818d0c54c0 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -493,25 +493,22 @@ static int online_store_recog_and_online(struct ccw_device *cdev) ccw_device_set_online(cdev); return 0; } -static void online_store_handle_online(struct ccw_device *cdev, int force) +static int online_store_handle_online(struct ccw_device *cdev, int force) { int ret; ret = online_store_recog_and_online(cdev); if (ret) - return; + return ret; if (force && cdev->private->state == DEV_STATE_BOXED) { ret = ccw_device_stlck(cdev); - if (ret) { - dev_warn(&cdev->dev, - "ccw_device_stlck returned %d!\n", ret); - return; - } + if (ret) + return ret; if (cdev->id.cu_type == 0) cdev->private->state = DEV_STATE_NOT_OPER; online_store_recog_and_online(cdev); } - + return 0; } static ssize_t online_store (struct device *dev, struct device_attribute *attr, @@ -544,8 +541,9 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr, ret = count; break; case 1: - online_store_handle_online(cdev, force); - ret = count; + ret = online_store_handle_online(cdev, force); + if (!ret) + ret = count; break; default: ret = -EINVAL; -- GitLab From ca366a329ad8eff1230decd55b33fe23326862f6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:23 +0200 Subject: [PATCH 1790/2509] [S390] Cleanup vtime printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/vtime.c | 56 +++++++++------------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index eb08d04bc1e..0fa5dc5d68e 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -318,8 +318,7 @@ static void internal_add_vtimer(struct vtimer_list *timer) vt_list = &per_cpu(virt_cpu_timer, timer->cpu); spin_lock_irqsave(&vt_list->lock, flags); - if (timer->cpu != smp_processor_id()) - printk("internal_add_vtimer: BUG, running on wrong CPU"); + BUG_ON(timer->cpu != smp_processor_id()); /* if list is empty we only have to set the timer */ if (list_empty(&vt_list->list)) { @@ -353,25 +352,12 @@ static void internal_add_vtimer(struct vtimer_list *timer) put_cpu(); } -static inline int prepare_vtimer(struct vtimer_list *timer) +static inline void prepare_vtimer(struct vtimer_list *timer) { - if (!timer->function) { - printk("add_virt_timer: uninitialized timer\n"); - return -EINVAL; - } - - if (!timer->expires || timer->expires > VTIMER_MAX_SLICE) { - printk("add_virt_timer: invalid timer expire value!\n"); - return -EINVAL; - } - - if (vtimer_pending(timer)) { - printk("add_virt_timer: timer pending\n"); - return -EBUSY; - } - + BUG_ON(!timer->function); + BUG_ON(!timer->expires || timer->expires > VTIMER_MAX_SLICE); + BUG_ON(vtimer_pending(timer)); timer->cpu = get_cpu(); - return 0; } /* @@ -382,10 +368,7 @@ void add_virt_timer(void *new) struct vtimer_list *timer; timer = (struct vtimer_list *)new; - - if (prepare_vtimer(timer) < 0) - return; - + prepare_vtimer(timer); timer->interval = 0; internal_add_vtimer(timer); } @@ -399,10 +382,7 @@ void add_virt_timer_periodic(void *new) struct vtimer_list *timer; timer = (struct vtimer_list *)new; - - if (prepare_vtimer(timer) < 0) - return; - + prepare_vtimer(timer); timer->interval = timer->expires; internal_add_vtimer(timer); } @@ -423,15 +403,8 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) unsigned long flags; int cpu; - if (!timer->function) { - printk("mod_virt_timer: uninitialized timer\n"); - return -EINVAL; - } - - if (!expires || expires > VTIMER_MAX_SLICE) { - printk("mod_virt_timer: invalid expire range\n"); - return -EINVAL; - } + BUG_ON(!timer->function); + BUG_ON(!expires || expires > VTIMER_MAX_SLICE); /* * This is a common optimization triggered by the @@ -444,6 +417,9 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) cpu = get_cpu(); vt_list = &per_cpu(virt_cpu_timer, cpu); + /* check if we run on the right CPU */ + BUG_ON(timer->cpu != cpu); + /* disable interrupts before test if timer is pending */ spin_lock_irqsave(&vt_list->lock, flags); @@ -458,14 +434,6 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) return 0; } - /* check if we run on the right CPU */ - if (timer->cpu != cpu) { - printk("mod_virt_timer: running on wrong CPU, check your code\n"); - spin_unlock_irqrestore(&vt_list->lock, flags); - put_cpu(); - return -EINVAL; - } - list_del_init(&timer->entry); timer->expires = expires; -- GitLab From 8df22b4b39c6a1679f471bd68f97cf6f6819571a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:24 +0200 Subject: [PATCH 1791/2509] [S390] Cleanup xpram printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/block/xpram.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index f231bc21b1c..dd9b986389a 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -100,15 +100,10 @@ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index) : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); if (cc == 3) return -ENXIO; - if (cc == 2) { - PRINT_ERR("expanded storage lost!\n"); + if (cc == 2) return -ENXIO; - } - if (cc == 1) { - PRINT_ERR("page in failed for page index %u.\n", - xpage_index); + if (cc == 1) return -EIO; - } return 0; } @@ -135,15 +130,10 @@ static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index) : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); if (cc == 3) return -ENXIO; - if (cc == 2) { - PRINT_ERR("expanded storage lost!\n"); + if (cc == 2) return -ENXIO; - } - if (cc == 1) { - PRINT_ERR("page out failed for page index %u.\n", - xpage_index); + if (cc == 1) return -EIO; - } return 0; } -- GitLab From a26182ed7171bff74caf5a55d4d3bdd6f400dfb5 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:25 +0200 Subject: [PATCH 1792/2509] [S390] Cleanup 3270 printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/fs3270.c | 5 +---- drivers/s390/char/raw3270.c | 1 - drivers/s390/char/tty3270.c | 3 --- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index f0d67af9640..e136d10a0de 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -512,11 +512,8 @@ fs3270_init(void) int rc; rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops); - if (rc) { - printk(KERN_ERR "fs3270 can't get major number %d: errno %d\n", - IBM_FS3270_MAJOR, rc); + if (rc) return rc; - } return 0; } diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index e2767e3b8cf..81a96e01908 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -610,7 +610,6 @@ __raw3270_size_device_vm(struct raw3270 *rp) rp->cols = 132; break; default: - printk(KERN_WARNING "vrdccrmd is 0x%.8x\n", model); rc = -EOPNOTSUPP; break; } diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index e4ba8bdce32..a7fe6302c98 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1792,15 +1792,12 @@ static int __init tty3270_init(void) tty_set_operations(driver, &tty3270_ops); ret = tty_register_driver(driver); if (ret) { - printk(KERN_ERR "tty3270 registration failed with %d\n", ret); put_tty_driver(driver); return ret; } tty3270_driver = driver; ret = raw3270_register_notifier(tty3270_notifier); if (ret) { - printk(KERN_ERR "tty3270 notifier registration failed " - "with %d\n", ret); put_tty_driver(driver); return ret; -- GitLab From 26348f78e84613371eb657ca1e584153ccb7d596 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:26 +0200 Subject: [PATCH 1793/2509] [S390] Cleanup 3215 printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/con3215.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 310eda82cde..4b632504c65 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -93,9 +93,6 @@ struct raw3215_info { struct raw3215_req *queued_write;/* pointer to queued write requests */ wait_queue_head_t empty_wait; /* wait queue for flushing */ struct timer_list timer; /* timer for delayed output */ - char *message; /* pending message from raw3215_irq */ - int msg_dstat; /* dstat for pending message */ - int msg_cstat; /* cstat for pending message */ int line_pos; /* position on the line (for tabs) */ char ubuffer[80]; /* copy_from_user buffer */ }; @@ -359,11 +356,6 @@ raw3215_tasklet(void *data) raw3215_mk_write_req(raw); raw3215_try_io(raw); spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); - /* Check for pending message from raw3215_irq */ - if (raw->message != NULL) { - printk(raw->message, raw->msg_dstat, raw->msg_cstat); - raw->message = NULL; - } tty = raw->tty; if (tty != NULL && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { @@ -387,14 +379,8 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) req = (struct raw3215_req *) intparm; cstat = irb->scsw.cmd.cstat; dstat = irb->scsw.cmd.dstat; - if (cstat != 0) { - raw->message = KERN_WARNING - "Got nonzero channel status in raw3215_irq " - "(dev sts 0x%2x, sch sts 0x%2x)"; - raw->msg_dstat = dstat; - raw->msg_cstat = cstat; + if (cstat != 0) tasklet_schedule(&raw->tasklet); - } if (dstat & 0x01) { /* we got a unit exception */ dstat &= ~0x01; /* we can ignore it */ } @@ -481,11 +467,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) raw->flags &= ~RAW3215_WORKING; raw3215_free_req(req); } - raw->message = KERN_WARNING - "Spurious interrupt in in raw3215_irq " - "(dev sts 0x%2x, sch sts 0x%2x)"; - raw->msg_dstat = dstat; - raw->msg_cstat = cstat; tasklet_schedule(&raw->tasklet); } return; @@ -883,7 +864,6 @@ con3215_init(void) free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE); free_bootmem((unsigned long) raw, sizeof(struct raw3215_info)); raw3215[0] = NULL; - printk("Couldn't find a 3215 console device\n"); return -ENODEV; } register_console(&con3215); @@ -1157,7 +1137,6 @@ tty3215_init(void) tty_set_operations(driver, &tty3215_ops); ret = tty_register_driver(driver); if (ret) { - printk("Couldn't register tty3215 driver\n"); put_tty_driver(driver); return ret; } -- GitLab From 1a89dd8f0b4d7eca2dd4abffb736f37676e1b073 Mon Sep 17 00:00:00 2001 From: Felix Beck Date: Mon, 14 Jul 2008 09:59:27 +0200 Subject: [PATCH 1794/2509] [S390] Cleanup zcrypt printk messages. Signed-off-by: Felix Beck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/crypto/zcrypt_api.c | 24 +++------- drivers/s390/crypto/zcrypt_api.h | 28 ------------ drivers/s390/crypto/zcrypt_cex2a.c | 3 -- drivers/s390/crypto/zcrypt_error.h | 6 --- drivers/s390/crypto/zcrypt_pcica.c | 3 -- drivers/s390/crypto/zcrypt_pcicc.c | 15 +------ drivers/s390/crypto/zcrypt_pcixcc.c | 68 +++++------------------------ 7 files changed, 17 insertions(+), 130 deletions(-) diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 4d36e805a23..8a4964f3584 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -1068,10 +1068,8 @@ static int zcrypt_status_write(struct file *file, const char __user *buffer, #define LBUFSIZE 1200UL lbuf = kmalloc(LBUFSIZE, GFP_KERNEL); - if (!lbuf) { - PRINTK("kmalloc failed!\n"); + if (!lbuf) return 0; - } local_count = min(LBUFSIZE - 1, count); if (copy_from_user(lbuf, buffer, local_count) != 0) { @@ -1081,23 +1079,15 @@ static int zcrypt_status_write(struct file *file, const char __user *buffer, lbuf[local_count] = '\0'; ptr = strstr(lbuf, "Online devices"); - if (!ptr) { - PRINTK("Unable to parse data (missing \"Online devices\")\n"); + if (!ptr) goto out; - } ptr = strstr(ptr, "\n"); - if (!ptr) { - PRINTK("Unable to parse data (missing newline " - "after \"Online devices\")\n"); + if (!ptr) goto out; - } ptr++; - if (strstr(ptr, "Waiting work element counts") == NULL) { - PRINTK("Unable to parse data (missing " - "\"Waiting work element counts\")\n"); + if (strstr(ptr, "Waiting work element counts") == NULL) goto out; - } for (j = 0; j < 64 && *ptr; ptr++) { /* @@ -1197,16 +1187,12 @@ int __init zcrypt_api_init(void) /* Register the request sprayer. */ rc = misc_register(&zcrypt_misc_device); - if (rc < 0) { - PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n", - zcrypt_misc_device.minor, rc); + if (rc < 0) goto out; - } /* Set up the proc file system */ zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL); if (!zcrypt_entry) { - PRINTK("Couldn't create z90crypt proc entry\n"); rc = -ENOMEM; goto out_misc; } diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index 5c6e222b2ac..1d1ec74dadb 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h @@ -30,34 +30,6 @@ #ifndef _ZCRYPT_API_H_ #define _ZCRYPT_API_H_ -/** - * Macro definitions - * - * PDEBUG debugs in the form "zcrypt: function_name -> message" - * - * PRINTK is like PDEBUG, except that it is always enabled - * PRINTKN is like PRINTK, except that it does not include the function name - * PRINTKW is like PRINTK, except that it uses KERN_WARNING - * PRINTKC is like PRINTK, except that it uses KERN_CRIT - */ -#define DEV_NAME "zcrypt" - -#define PRINTK(fmt, args...) \ - printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __func__ , ## args) -#define PRINTKN(fmt, args...) \ - printk(KERN_DEBUG DEV_NAME ": " fmt, ## args) -#define PRINTKW(fmt, args...) \ - printk(KERN_WARNING DEV_NAME ": %s -> " fmt, __func__ , ## args) -#define PRINTKC(fmt, args...) \ - printk(KERN_CRIT DEV_NAME ": %s -> " fmt, __func__ , ## args) - -#ifdef ZCRYPT_DEBUG -#define PDEBUG(fmt, args...) \ - printk(KERN_DEBUG DEV_NAME ": %s -> " fmt, __func__ , ## args) -#else -#define PDEBUG(fmt, args...) do {} while (0) -#endif - #include "ap_bus.h" #include diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 78ffba1dd61..54f4cbc3be9 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c @@ -243,9 +243,6 @@ static int convert_response(struct zcrypt_device *zdev, return convert_type80(zdev, reply, outputdata, outputdatalength); default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } diff --git a/drivers/s390/crypto/zcrypt_error.h b/drivers/s390/crypto/zcrypt_error.h index 3e27fe77d20..03ba27f05f9 100644 --- a/drivers/s390/crypto/zcrypt_error.h +++ b/drivers/s390/crypto/zcrypt_error.h @@ -92,10 +92,6 @@ static inline int convert_error(struct zcrypt_device *zdev, { struct error_hdr *ehdr = reply->message; - PRINTK("Hardware error : Type %02x Message Header: %08x%08x\n", - ehdr->type, *(unsigned int *) reply->message, - *(unsigned int *) (reply->message + 4)); - switch (ehdr->reply_code) { case REP82_ERROR_OPERAND_INVALID: case REP82_ERROR_OPERAND_SIZE: @@ -123,8 +119,6 @@ static inline int convert_error(struct zcrypt_device *zdev, zdev->online = 0; return -EAGAIN; default: - PRINTKW("unknown type %02x reply code = %d\n", - ehdr->type, ehdr->reply_code); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 6e93b475178..12da4815ba8 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c @@ -226,9 +226,6 @@ static int convert_response(struct zcrypt_device *zdev, return convert_type84(zdev, reply, outputdata, outputdatalength); default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index 17ea56ce1c1..779952cb19f 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c @@ -361,26 +361,18 @@ static int convert_type86(struct zcrypt_device *zdev, service_rc = le16_to_cpu(msg->cprb.ccp_rtcode); if (unlikely(service_rc != 0)) { service_rs = le16_to_cpu(msg->cprb.ccp_rscode); - if (service_rc == 8 && service_rs == 66) { - PDEBUG("Bad block format on PCICC\n"); + if (service_rc == 8 && service_rs == 66) return -EINVAL; - } - if (service_rc == 8 && service_rs == 65) { - PDEBUG("Probably an even modulus on PCICC\n"); + if (service_rc == 8 && service_rs == 65) return -EINVAL; - } if (service_rc == 8 && service_rs == 770) { - PDEBUG("Invalid key length on PCICC\n"); zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD; return -EAGAIN; } if (service_rc == 8 && service_rs == 783) { - PDEBUG("Extended bitlengths not enabled on PCICC\n"); zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD; return -EAGAIN; } - PRINTK("Unknown service rc/rs (PCICC): %d/%d\n", - service_rc, service_rs); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } @@ -434,9 +426,6 @@ static int convert_response(struct zcrypt_device *zdev, outputdata, outputdatalength); /* no break, incorrect cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 4040c1c981d..d8ad36f8154 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c @@ -290,38 +290,19 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, ap_msg->length = sizeof(struct type6_hdr) + CEIL4(xcRB->request_control_blk_length) + xcRB->request_data_length; - if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) { - PRINTK("Combined message is too large (%ld/%d/%d).\n", - sizeof(struct type6_hdr), - xcRB->request_control_blk_length, - xcRB->request_data_length); + if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) return -EFAULT; - } - if (CEIL4(xcRB->reply_control_blk_length) > - PCIXCC_MAX_XCRB_REPLY_SIZE) { - PDEBUG("Reply CPRB length is too large (%d).\n", - xcRB->request_control_blk_length); + if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE) return -EFAULT; - } - if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) { - PDEBUG("Reply data block length is too large (%d).\n", - xcRB->reply_data_length); + if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) return -EFAULT; - } replylen = CEIL4(xcRB->reply_control_blk_length) + CEIL4(xcRB->reply_data_length) + sizeof(struct type86_fmt2_msg); if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) { - PDEBUG("Reply CPRB + data block > PCIXCC_MAX_XCRB_RESPONSE_SIZE" - " (%d/%d/%d).\n", - sizeof(struct type86_fmt2_msg), - xcRB->reply_control_blk_length, - xcRB->reply_data_length); xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE - (sizeof(struct type86_fmt2_msg) + CEIL4(xcRB->reply_data_length)); - PDEBUG("Capping Reply CPRB length at %d\n", - xcRB->reply_control_blk_length); } /* prepare type6 header */ @@ -340,11 +321,8 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, xcRB->request_control_blk_length)) return -EFAULT; if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > - xcRB->request_control_blk_length) { - PDEBUG("cprb_len too large (%d/%d)\n", msg->cprbx.cprb_len, - xcRB->request_control_blk_length); + xcRB->request_control_blk_length) return -EFAULT; - } function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); @@ -472,29 +450,18 @@ static int convert_type86_ica(struct zcrypt_device *zdev, service_rc = msg->cprbx.ccp_rtcode; if (unlikely(service_rc != 0)) { service_rs = msg->cprbx.ccp_rscode; - if (service_rc == 8 && service_rs == 66) { - PDEBUG("Bad block format on PCIXCC/CEX2C\n"); + if (service_rc == 8 && service_rs == 66) return -EINVAL; - } - if (service_rc == 8 && service_rs == 65) { - PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n"); + if (service_rc == 8 && service_rs == 65) return -EINVAL; - } - if (service_rc == 8 && service_rs == 770) { - PDEBUG("Invalid key length on PCIXCC/CEX2C\n"); + if (service_rc == 8 && service_rs == 770) return -EINVAL; - } if (service_rc == 8 && service_rs == 783) { - PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n"); zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; return -EAGAIN; } - if (service_rc == 12 && service_rs == 769) { - PDEBUG("Invalid key on PCIXCC/CEX2C\n"); + if (service_rc == 12 && service_rs == 769) return -EINVAL; - } - PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n", - service_rc, service_rs); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } @@ -570,11 +537,8 @@ static int convert_type86_rng(struct zcrypt_device *zdev, } __attribute__((packed)) *msg = reply->message; char *data = reply->message; - if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) { - PDEBUG("RNG response error on PCIXCC/CEX2C rc=%hu/rs=%hu\n", - rc, rs); + if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) return -EINVAL; - } memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2); return msg->fmt2.count2; } @@ -599,9 +563,6 @@ static int convert_response_ica(struct zcrypt_device *zdev, outputdata, outputdatalength); /* no break, incorrect cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } @@ -628,9 +589,6 @@ static int convert_response_xcrb(struct zcrypt_device *zdev, return convert_type86_xcrb(zdev, reply, xcRB); /* no break, incorrect cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ @@ -654,9 +612,6 @@ static int convert_response_rng(struct zcrypt_device *zdev, return convert_type86_rng(zdev, reply, data); /* no break, incorrect cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; return -EAGAIN; /* repeat the request on a different device. */ } @@ -701,10 +656,7 @@ static void zcrypt_pcixcc_receive(struct ap_device *ap_dev, memcpy(msg->message, reply->message, length); break; default: - PRINTK("Invalid internal response type: %i\n", - resp_type->type); - memcpy(msg->message, &error_reply, - sizeof error_reply); + memcpy(msg->message, &error_reply, sizeof error_reply); } } else memcpy(msg->message, reply->message, sizeof error_reply); -- GitLab From a12c53f4fa759b59654b6d5f21eb4070cd45cd54 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:28 +0200 Subject: [PATCH 1795/2509] [S390] Cleanup sclp printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp.c | 8 +++----- drivers/s390/char/sclp_con.c | 2 -- drivers/s390/char/sclp_config.c | 4 +--- drivers/s390/char/sclp_cpi_sys.c | 12 ++---------- drivers/s390/char/sclp_quiesce.c | 8 +------- drivers/s390/char/sclp_rw.c | 2 -- drivers/s390/char/sclp_sdias.c | 4 +--- drivers/s390/char/sclp_tty.c | 8 -------- drivers/s390/char/sclp_vt220.c | 7 +------ 9 files changed, 9 insertions(+), 46 deletions(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 277f9ccfbb7..fb97cf5ee67 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -784,11 +784,9 @@ sclp_check_handler(__u16 code) /* Is this the interrupt we are waiting for? */ if (finished_sccb == 0) return; - if (finished_sccb != (u32) (addr_t) sclp_init_sccb) { - printk(KERN_WARNING SCLP_HEADER "unsolicited interrupt " - "for buffer at 0x%x\n", finished_sccb); - return; - } + if (finished_sccb != (u32) (addr_t) sclp_init_sccb) + panic("sclp: unsolicited interrupt for buffer at 0x%x\n", + finished_sccb); spin_lock(&sclp_lock); if (sclp_running_state == sclp_running_state_running) { sclp_init_req.status = SCLP_REQ_DONE; diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c index 23bb90a5ed2..0ddf1b7c00d 100644 --- a/drivers/s390/char/sclp_con.c +++ b/drivers/s390/char/sclp_con.c @@ -20,8 +20,6 @@ #include "sclp_rw.h" #include "sclp_tty.h" -#define SCLP_CON_PRINT_HEADER "sclp console driver: " - #define sclp_console_major 4 /* TTYAUX_MAJOR */ #define sclp_console_minor 64 #define sclp_console_name "ttyS" diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 7c9b39cee59..fff4ff485d9 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -85,10 +85,8 @@ static int __init sclp_conf_init(void) INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); rc = sclp_register(&sclp_conf_register); - if (rc) { - printk(KERN_ERR TAG "failed to register (%d).\n", rc); + if (rc) return rc; - } if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) { printk(KERN_WARNING TAG "no configuration management.\n"); diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index 005f330ed92..d887bd261d2 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -126,21 +126,15 @@ static int cpi_req(void) int response; rc = sclp_register(&sclp_cpi_event); - if (rc) { - printk(KERN_WARNING "cpi: could not register " - "to hardware console.\n"); + if (rc) goto out; - } if (!(sclp_cpi_event.sclp_receive_mask & EVTYP_CTLPROGIDENT_MASK)) { - printk(KERN_WARNING "cpi: no control program " - "identification support\n"); rc = -EOPNOTSUPP; goto out_unregister; } req = cpi_prepare_req(); if (IS_ERR(req)) { - printk(KERN_WARNING "cpi: could not allocate request\n"); rc = PTR_ERR(req); goto out_unregister; } @@ -150,10 +144,8 @@ static int cpi_req(void) /* Add request to sclp queue */ rc = sclp_add_request(req); - if (rc) { - printk(KERN_WARNING "cpi: could not start request\n"); + if (rc) goto out_free_req; - } wait_for_completion(&completion); diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c index 45ff25e787c..84c191c1cd6 100644 --- a/drivers/s390/char/sclp_quiesce.c +++ b/drivers/s390/char/sclp_quiesce.c @@ -51,13 +51,7 @@ static struct sclp_register sclp_quiesce_event = { static int __init sclp_quiesce_init(void) { - int rc; - - rc = sclp_register(&sclp_quiesce_event); - if (rc) - printk(KERN_WARNING "sclp: could not register quiesce handler " - "(rc=%d)\n", rc); - return rc; + return sclp_register(&sclp_quiesce_event); } module_init(sclp_quiesce_init); diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index da09781b32f..710af42603f 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -19,8 +19,6 @@ #include "sclp.h" #include "sclp_rw.h" -#define SCLP_RW_PRINT_HEADER "sclp low level driver: " - /* * The room for the SCCB (only for writing) is not equal to a pages size * (as it is specified as the maximum size in the SCLP documentation) diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index 1c064976b32..8b854857ba0 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -239,10 +239,8 @@ int __init sclp_sdias_init(void) debug_register_view(sdias_dbf, &debug_sprintf_view); debug_set_level(sdias_dbf, 6); rc = sclp_register(&sclp_sdias_register); - if (rc) { - ERROR_MSG("sclp register failed\n"); + if (rc) return rc; - } init_waitqueue_head(&sdias_wq); TRACE("init done\n"); return 0; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 40b11521cd2..d3b1957cd2f 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -25,8 +25,6 @@ #include "sclp_rw.h" #include "sclp_tty.h" -#define SCLP_TTY_PRINT_HEADER "sclp tty driver: " - /* * size of a buffer that collects single characters coming in * via sclp_tty_put_char() @@ -736,9 +734,6 @@ sclp_tty_init(void) rc = sclp_rw_init(); if (rc) { - printk(KERN_ERR SCLP_TTY_PRINT_HEADER - "could not register tty - " - "sclp_rw_init returned %d\n", rc); put_tty_driver(driver); return rc; } @@ -792,9 +787,6 @@ sclp_tty_init(void) tty_set_operations(driver, &sclp_ops); rc = tty_register_driver(driver); if (rc) { - printk(KERN_ERR SCLP_TTY_PRINT_HEADER - "could not register tty - " - "tty_register_driver returned %d\n", rc); put_tty_driver(driver); return rc; } diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index baea4d54852..ad51738c426 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -27,7 +27,6 @@ #include #include "sclp.h" -#define SCLP_VT220_PRINT_HEADER "sclp vt220 tty driver: " #define SCLP_VT220_MAJOR TTY_MAJOR #define SCLP_VT220_MINOR 65 #define SCLP_VT220_DRIVER_NAME "sclp_vt220" @@ -716,12 +715,8 @@ static int __init sclp_vt220_tty_init(void) tty_set_operations(driver, &sclp_vt220_ops); rc = tty_register_driver(driver); - if (rc) { - printk(KERN_ERR SCLP_VT220_PRINT_HEADER - "could not register tty - " - "tty_register_driver returned %d\n", rc); + if (rc) goto out_init; - } sclp_vt220_driver = driver; return 0; -- GitLab From c2b4afd2f99a187ec3bbd6e2def186fbfb755929 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 14 Jul 2008 09:59:29 +0200 Subject: [PATCH 1796/2509] [S390] Cleanup iucv printk messages. Cc: David S. Miller Signed-off-by: Ursula Braun Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- net/iucv/af_iucv.c | 8 ++------ net/iucv/iucv.c | 9 ++------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 7b0038f45b1..bda71015885 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -1135,8 +1135,7 @@ static void iucv_callback_txdone(struct iucv_path *path, if (this) kfree_skb(this); } - if (!this) - printk(KERN_ERR "AF_IUCV msg tag %u not found\n", msg->tag); + BUG_ON(!this); if (sk->sk_state == IUCV_CLOSING) { if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) { @@ -1196,7 +1195,7 @@ static int __init afiucv_init(void) } cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); if (unlikely(err)) { - printk(KERN_ERR "AF_IUCV needs the VM userid\n"); + WARN_ON(err); err = -EPROTONOSUPPORT; goto out; } @@ -1210,7 +1209,6 @@ static int __init afiucv_init(void) err = sock_register(&iucv_sock_family_ops); if (err) goto out_proto; - printk(KERN_INFO "AF_IUCV lowlevel driver initialized\n"); return 0; out_proto: @@ -1226,8 +1224,6 @@ static void __exit afiucv_exit(void) sock_unregister(PF_IUCV); proto_unregister(&iucv_proto); iucv_unregister(&af_iucv_handler, 0); - - printk(KERN_INFO "AF_IUCV lowlevel driver unloaded\n"); } module_init(afiucv_init); diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 91897076213..7f82b761621 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -1559,16 +1559,11 @@ static void iucv_external_interrupt(u16 code) p = iucv_irq_data[smp_processor_id()]; if (p->ippathid >= iucv_max_pathid) { - printk(KERN_WARNING "iucv_do_int: Got interrupt with " - "pathid %d > max_connections (%ld)\n", - p->ippathid, iucv_max_pathid - 1); + WARN_ON(p->ippathid >= iucv_max_pathid); iucv_sever_pathid(p->ippathid, iucv_error_no_listener); return; } - if (p->iptype < 0x01 || p->iptype > 0x09) { - printk(KERN_ERR "iucv_do_int: unknown iucv interrupt\n"); - return; - } + BUG_ON(p->iptype < 0x01 || p->iptype > 0x09); work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); if (!work) { printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); -- GitLab From f082bcae72575714823ea2ea9447332642127d9c Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 14 Jul 2008 09:59:30 +0200 Subject: [PATCH 1797/2509] [S390] Cleanup netiucv printk messages. Cc: Jeff Garzik Signed-off-by: Ursula Braun Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/net/netiucv.c | 61 ++++++-------------------------------- 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index e4ba6a0372a..9242b5acc66 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -625,9 +625,6 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, offset += header->next; header->next -= NETIUCV_HDRLEN; if (skb_tailroom(pskb) < header->next) { - PRINT_WARN("%s: Illegal next field in iucv header: " - "%d > %d\n", - dev->name, header->next, skb_tailroom(pskb)); IUCV_DBF_TEXT_(data, 2, "Illegal next field: %d > %d\n", header->next, skb_tailroom(pskb)); return; @@ -636,8 +633,6 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, skb_reset_mac_header(pskb); skb = dev_alloc_skb(pskb->len); if (!skb) { - PRINT_WARN("%s Out of memory in netiucv_unpack_skb\n", - dev->name); IUCV_DBF_TEXT(data, 2, "Out of memory in netiucv_unpack_skb\n"); privptr->stats.rx_dropped++; @@ -674,7 +669,6 @@ static void conn_action_rx(fsm_instance *fi, int event, void *arg) if (!conn->netdev) { iucv_message_reject(conn->path, msg); - PRINT_WARN("Received data for unlinked connection\n"); IUCV_DBF_TEXT(data, 2, "Received data for unlinked connection\n"); return; @@ -682,8 +676,6 @@ static void conn_action_rx(fsm_instance *fi, int event, void *arg) if (msg->length > conn->max_buffsize) { iucv_message_reject(conn->path, msg); privptr->stats.rx_dropped++; - PRINT_WARN("msglen %d > max_buffsize %d\n", - msg->length, conn->max_buffsize); IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n", msg->length, conn->max_buffsize); return; @@ -695,7 +687,6 @@ static void conn_action_rx(fsm_instance *fi, int event, void *arg) msg->length, NULL); if (rc || msg->length < 5) { privptr->stats.rx_errors++; - PRINT_WARN("iucv_receive returned %08x\n", rc); IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc); return; } @@ -778,7 +769,6 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg) fsm_newstate(fi, CONN_STATE_IDLE); if (privptr) privptr->stats.tx_errors += txpackets; - PRINT_WARN("iucv_send returned %08x\n", rc); IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); } else { if (privptr) { @@ -806,8 +796,6 @@ static void conn_action_connaccept(fsm_instance *fi, int event, void *arg) path->flags = 0; rc = iucv_path_accept(path, &netiucv_handler, NULL, conn); if (rc) { - PRINT_WARN("%s: IUCV accept failed with error %d\n", - netdev->name, rc); IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc); return; } @@ -873,7 +861,7 @@ static void conn_action_start(fsm_instance *fi, int event, void *arg) IUCV_DBF_TEXT(trace, 3, __func__); fsm_newstate(fi, CONN_STATE_STARTWAIT); - PRINT_DEBUG("%s('%s'): connecting ...\n", + IUCV_DBF_TEXT_(setup, 2, "%s('%s'): connecting ...\n", conn->netdev->name, conn->userid); /* @@ -968,8 +956,8 @@ static void conn_action_inval(fsm_instance *fi, int event, void *arg) struct iucv_connection *conn = arg; struct net_device *netdev = conn->netdev; - PRINT_WARN("%s: Cannot connect without username\n", netdev->name); - IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n"); + IUCV_DBF_TEXT_(data, 2, "%s('%s'): conn_action_inval called\n", + netdev->name, conn->userid); } static const fsm_node conn_fsm[] = { @@ -1077,9 +1065,6 @@ dev_action_connup(fsm_instance *fi, int event, void *arg) "connection is up and running\n"); break; case DEV_STATE_STOPWAIT: - PRINT_INFO( - "%s: got connection UP event during shutdown!\n", - dev->name); IUCV_DBF_TEXT(data, 2, "dev_action_connup: in DEV_STATE_STOPWAIT\n"); break; @@ -1174,8 +1159,6 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, nskb = alloc_skb(skb->len + NETIUCV_HDRLEN + NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA); if (!nskb) { - PRINT_WARN("%s: Could not allocate tx_skb\n", - conn->netdev->name); IUCV_DBF_TEXT(data, 2, "alloc_skb failed\n"); rc = -ENOMEM; return rc; @@ -1223,7 +1206,6 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, skb_pull(skb, NETIUCV_HDRLEN); skb_trim(skb, skb->len - NETIUCV_HDRLEN); } - PRINT_WARN("iucv_send returned %08x\n", rc); IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); } else { if (copied) @@ -1293,14 +1275,11 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) * Some sanity checks ... */ if (skb == NULL) { - PRINT_WARN("%s: NULL sk_buff passed\n", dev->name); IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n"); privptr->stats.tx_dropped++; return 0; } if (skb_headroom(skb) < NETIUCV_HDRLEN) { - PRINT_WARN("%s: Got sk_buff with head room < %ld bytes\n", - dev->name, NETIUCV_HDRLEN); IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n"); dev_kfree_skb(skb); @@ -1393,7 +1372,6 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr, IUCV_DBF_TEXT(trace, 3, __func__); if (count > 9) { - PRINT_WARN("netiucv: username too long (%d)!\n", (int) count); IUCV_DBF_TEXT_(setup, 2, "%d is length of username\n", (int) count); return -EINVAL; @@ -1409,7 +1387,6 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr, /* trailing lf, grr */ break; } - PRINT_WARN("netiucv: Invalid char %c in username!\n", *p); IUCV_DBF_TEXT_(setup, 2, "username: invalid character %c\n", *p); return -EINVAL; @@ -1421,18 +1398,15 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr, if (memcmp(username, priv->conn->userid, 9) && (ndev->flags & (IFF_UP | IFF_RUNNING))) { /* username changed while the interface is active. */ - PRINT_WARN("netiucv: device %s active, connected to %s\n", - dev->bus_id, priv->conn->userid); - PRINT_WARN("netiucv: user cannot be updated\n"); IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); - return -EBUSY; + return -EPERM; } read_lock_bh(&iucv_connection_rwlock); list_for_each_entry(cp, &iucv_connection_list, list) { if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) { read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); + IUCV_DBF_TEXT_(setup, 2, "user_write: Connection " + "to %s already exists\n", username); return -EEXIST; } } @@ -1466,13 +1440,10 @@ static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, bs1 = simple_strtoul(buf, &e, 0); if (e && (!isspace(*e))) { - PRINT_WARN("netiucv: Invalid character in buffer!\n"); IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %c\n", *e); return -EINVAL; } if (bs1 > NETIUCV_BUFSIZE_MAX) { - PRINT_WARN("netiucv: Given buffer size %d too large.\n", - bs1); IUCV_DBF_TEXT_(setup, 2, "buffer_write: buffer size %d too large\n", bs1); @@ -1480,16 +1451,12 @@ static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, } if ((ndev->flags & IFF_RUNNING) && (bs1 < (ndev->mtu + NETIUCV_HDRLEN + 2))) { - PRINT_WARN("netiucv: Given buffer size %d too small.\n", - bs1); IUCV_DBF_TEXT_(setup, 2, "buffer_write: buffer size %d too small\n", bs1); return -EINVAL; } if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN)) { - PRINT_WARN("netiucv: Given buffer size %d too small.\n", - bs1); IUCV_DBF_TEXT_(setup, 2, "buffer_write: buffer size %d too small\n", bs1); @@ -1963,7 +1930,6 @@ static ssize_t conn_write(struct device_driver *drv, IUCV_DBF_TEXT(trace, 3, __func__); if (count>9) { - PRINT_WARN("netiucv: username too long (%d)!\n", (int)count); IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n"); return -EINVAL; } @@ -1976,7 +1942,6 @@ static ssize_t conn_write(struct device_driver *drv, if (*p == '\n') /* trailing lf, grr */ break; - PRINT_WARN("netiucv: Invalid character in username!\n"); IUCV_DBF_TEXT_(setup, 2, "conn_write: invalid character %c\n", *p); return -EINVAL; @@ -1989,8 +1954,8 @@ static ssize_t conn_write(struct device_driver *drv, list_for_each_entry(cp, &iucv_connection_list, list) { if (!strncmp(username, cp->userid, 9)) { read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); + IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection " + "to %s already exists\n", username); return -EEXIST; } } @@ -1998,9 +1963,6 @@ static ssize_t conn_write(struct device_driver *drv, dev = netiucv_init_netdevice(username); if (!dev) { - PRINT_WARN("netiucv: Could not allocate network device " - "structure for user '%s'\n", - netiucv_printname(username)); IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n"); return -ENODEV; } @@ -2020,15 +1982,12 @@ static ssize_t conn_write(struct device_driver *drv, if (rc) goto out_unreg; - PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username)); return count; out_unreg: netiucv_unregister_device(priv->dev); out_free_ndev: - PRINT_WARN("netiucv: Could not register '%s'\n", dev->name); - IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n"); netiucv_free_netdevice(dev); return rc; } @@ -2073,14 +2032,13 @@ static ssize_t remove_write (struct device_driver *drv, PRINT_WARN("netiucv: %s cannot be removed\n", ndev->name); IUCV_DBF_TEXT(data, 2, "remove_write: still active\n"); - return -EBUSY; + return -EPERM; } unregister_netdev(ndev); netiucv_unregister_device(dev); return count; } read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: net device %s unknown\n", name); IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); return -EINVAL; } @@ -2148,7 +2106,6 @@ static int __init netiucv_init(void) netiucv_driver.groups = netiucv_drv_attr_groups; rc = driver_register(&netiucv_driver); if (rc) { - PRINT_ERR("NETIUCV: failed to register driver.\n"); IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); goto out_iucv; } -- GitLab From c4cef07cf39e18e9211a674d99cafde434b45a81 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 14 Jul 2008 09:59:31 +0200 Subject: [PATCH 1798/2509] [S390] Cleanup qeth print messages. Cc: Jeff Garzik Signed-off-by: Frank Blaschka Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/net/qeth_core_main.c | 3 +-- drivers/s390/net/qeth_l3_main.c | 9 +-------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 90db3e444f3..0ac54dc638c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -420,7 +420,7 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, QETH_DBF_TEXT(TRACE, 3, "urla"); break; default: - PRINT_WARN("Received data is IPA " + QETH_DBF_MESSAGE(2, "Received data is IPA " "but not a reply!\n"); break; } @@ -4092,7 +4092,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) rc = qeth_determine_card_type(card); if (rc) { - PRINT_WARN("%s: not a valid card type\n", __func__); QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); goto err_card; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 999552c83bb..06deaee50f6 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -944,15 +944,8 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card, else rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP, addr->del_flags); - if (rc) { + if (rc) QETH_DBF_TEXT(TRACE, 2, "failed"); - /* TODO: re-activate this warning as soon as we have a - * clean mirco code - qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf); - PRINT_WARN("Could not deregister IP address %s (rc=%x)\n", - buf, rc); - */ - } return rc; } -- GitLab From d4ebabe8cae5a9265eb55b7f873b6b7d92c0cdd6 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Mon, 14 Jul 2008 09:59:32 +0200 Subject: [PATCH 1799/2509] [S390] Cleanup cpacf printk messages. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/crypto/prng.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 0cfefddd837..6a4300b3ff5 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -185,11 +185,8 @@ static int __init prng_init(void) prng_seed(16); ret = misc_register(&prng_dev); - if (ret) { - printk(KERN_WARNING - "Could not register misc device for PRNG.\n"); + if (ret) goto out_buf; - } return 0; out_buf: -- GitLab From d5ddc809bf3e63a9cd6d02062f6a7c86bcff7fea Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:33 +0200 Subject: [PATCH 1800/2509] [S390] Cleanup smsgiucv printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/net/smsgiucv.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 8735a415a11..164e090c262 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -156,11 +156,8 @@ static int __init smsg_init(void) if (rc != 0) goto out; rc = iucv_register(&smsg_handler, 1); - if (rc) { - printk(KERN_ERR "SMSGIUCV: failed to register to iucv"); - rc = -EIO; /* better errno ? */ + if (rc) goto out_driver; - } smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL); if (!smsg_path) { rc = -ENOMEM; @@ -168,11 +165,8 @@ static int __init smsg_init(void) } rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", NULL, NULL, NULL); - if (rc) { - printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); - rc = -EIO; /* better errno ? */ + if (rc) goto out_free; - } cpcmd("SET SMSG IUCV", NULL, 0, NULL); return 0; -- GitLab From d3ae942d185bdb9b84a661889fc3349044eeb260 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 14 Jul 2008 09:59:34 +0200 Subject: [PATCH 1801/2509] [S390] Cleanup appldata printk messages. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/appldata/appldata.h | 10 +---- arch/s390/appldata/appldata_base.c | 39 +++--------------- arch/s390/appldata/appldata_mem.c | 43 +------------------- arch/s390/appldata/appldata_net_sum.c | 39 +----------------- arch/s390/appldata/appldata_os.c | 57 +-------------------------- 5 files changed, 11 insertions(+), 177 deletions(-) diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h index db3ae850510..17a2636fec0 100644 --- a/arch/s390/appldata/appldata.h +++ b/arch/s390/appldata/appldata.h @@ -3,13 +3,11 @@ * * Definitions and interface for Linux - z/VM Monitor Stream. * - * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright IBM Corp. 2003, 2008 * * Author: Gerald Schaefer */ -//#define APPLDATA_DEBUG /* Debug messages on/off */ - #define APPLDATA_MAX_REC_SIZE 4024 /* Maximum size of the */ /* data buffer */ #define APPLDATA_MAX_PROCS 100 @@ -32,12 +30,6 @@ #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) -#ifdef APPLDATA_DEBUG -#define P_DEBUG(x...) printk(KERN_DEBUG MY_PRINT_NAME " debug: " x) -#else -#define P_DEBUG(x...) do {} while (0) -#endif - struct appldata_ops { struct list_head list; struct ctl_table_header *sysctl_header; diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 803f3645edf..9cb3d92447a 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -5,7 +5,7 @@ * Exports appldata_register_ops() and appldata_unregister_ops() for the * data gathering modules. * - * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright IBM Corp. 2003, 2008 * * Author: Gerald Schaefer */ @@ -108,9 +108,6 @@ static LIST_HEAD(appldata_ops_list); */ static void appldata_timer_function(unsigned long data) { - P_DEBUG(" -= Timer =-\n"); - P_DEBUG("CPU: %i, expire_count: %i\n", smp_processor_id(), - atomic_read(&appldata_expire_count)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); queue_work(appldata_wq, (struct work_struct *) data); @@ -128,14 +125,11 @@ static void appldata_work_fn(struct work_struct *work) struct appldata_ops *ops; int i; - P_DEBUG(" -= Work Queue =-\n"); i = 0; get_online_cpus(); spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); - P_DEBUG("list_for_each loop: %i) active = %u, name = %s\n", - ++i, ops->active, ops->name); if (ops->active == 1) { ops->callback(ops->data); } @@ -212,7 +206,6 @@ __appldata_vtimer_setup(int cmd) 0, 1); } appldata_timer_active = 1; - P_INFO("Monitoring timer started.\n"); break; case APPLDATA_DEL_TIMER: for_each_online_cpu(i) @@ -221,7 +214,6 @@ __appldata_vtimer_setup(int cmd) break; appldata_timer_active = 0; atomic_set(&appldata_expire_count, num_online_cpus()); - P_INFO("Monitoring timer stopped.\n"); break; case APPLDATA_MOD_TIMER: per_cpu_interval = (u64) (appldata_interval*1000 / @@ -313,10 +305,8 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, } interval = 0; sscanf(buf, "%i", &interval); - if (interval <= 0) { - P_ERROR("Timer CPU interval has to be > 0!\n"); + if (interval <= 0) return -EINVAL; - } get_online_cpus(); spin_lock(&appldata_timer_lock); @@ -324,9 +314,6 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, __appldata_vtimer_setup(APPLDATA_MOD_TIMER); spin_unlock(&appldata_timer_lock); put_online_cpus(); - - P_INFO("Monitoring CPU interval set to %u milliseconds.\n", - interval); out: *lenp = len; *ppos += len; @@ -406,23 +393,16 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, P_ERROR("START DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); module_put(ops->owner); - } else { - P_INFO("Monitoring %s data enabled, " - "DIAG 0xDC started.\n", ops->name); + } else ops->active = 1; - } } else if ((buf[0] == '0') && (ops->active == 1)) { ops->active = 0; rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, (unsigned long) ops->data, ops->size, ops->mod_lvl); - if (rc != 0) { + if (rc != 0) P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); - } else { - P_INFO("Monitoring %s data disabled, " - "DIAG 0xDC stopped.\n", ops->name); - } module_put(ops->owner); } spin_unlock(&appldata_ops_lock); @@ -468,7 +448,6 @@ int appldata_register_ops(struct appldata_ops *ops) ops->sysctl_header = register_sysctl_table(ops->ctl_table); if (!ops->sysctl_header) goto out; - P_INFO("%s-ops registered!\n", ops->name); return 0; out: spin_lock(&appldata_ops_lock); @@ -490,7 +469,6 @@ void appldata_unregister_ops(struct appldata_ops *ops) spin_unlock(&appldata_ops_lock); unregister_sysctl_table(ops->sysctl_header); kfree(ops->ctl_table); - P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management **************************/ @@ -553,14 +531,9 @@ static int __init appldata_init(void) { int i; - P_DEBUG("sizeof(parameter_list) = %lu\n", - sizeof(struct appldata_parameter_list)); - appldata_wq = create_singlethread_workqueue("appldata"); - if (!appldata_wq) { - P_ERROR("Could not create work queue\n"); + if (!appldata_wq) return -ENOMEM; - } get_online_cpus(); for_each_online_cpu(i) @@ -571,8 +544,6 @@ static int __init appldata_init(void) register_hotcpu_notifier(&appldata_nb); appldata_sysctl_header = register_sysctl_table(appldata_dir_table); - - P_DEBUG("Base interface initialized.\n"); return 0; } diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 51181ccdb87..3ed56b7d1b2 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -14,14 +14,13 @@ #include #include #include -#include #include #include +#include #include "appldata.h" -#define MY_PRINT_NAME "appldata_mem" /* for debug messages, etc. */ #define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* Converts #Pages to KB */ /* @@ -70,30 +69,6 @@ static struct appldata_mem_data { } __attribute__((packed)) appldata_mem_data; -static inline void appldata_debug_print(struct appldata_mem_data *mem_data) -{ - P_DEBUG("--- MEM - RECORD ---\n"); - P_DEBUG("pgpgin = %8lu KB\n", mem_data->pgpgin); - P_DEBUG("pgpgout = %8lu KB\n", mem_data->pgpgout); - P_DEBUG("pswpin = %8lu Pages\n", mem_data->pswpin); - P_DEBUG("pswpout = %8lu Pages\n", mem_data->pswpout); - P_DEBUG("pgalloc = %8lu \n", mem_data->pgalloc); - P_DEBUG("pgfault = %8lu \n", mem_data->pgfault); - P_DEBUG("pgmajfault = %8lu \n", mem_data->pgmajfault); - P_DEBUG("sharedram = %8lu KB\n", mem_data->sharedram); - P_DEBUG("totalram = %8lu KB\n", mem_data->totalram); - P_DEBUG("freeram = %8lu KB\n", mem_data->freeram); - P_DEBUG("totalhigh = %8lu KB\n", mem_data->totalhigh); - P_DEBUG("freehigh = %8lu KB\n", mem_data->freehigh); - P_DEBUG("bufferram = %8lu KB\n", mem_data->bufferram); - P_DEBUG("cached = %8lu KB\n", mem_data->cached); - P_DEBUG("totalswap = %8lu KB\n", mem_data->totalswap); - P_DEBUG("freeswap = %8lu KB\n", mem_data->freeswap); - P_DEBUG("sync_count_1 = %u\n", mem_data->sync_count_1); - P_DEBUG("sync_count_2 = %u\n", mem_data->sync_count_2); - P_DEBUG("timestamp = %lX\n", mem_data->timestamp); -} - /* * appldata_get_mem_data() * @@ -140,9 +115,6 @@ static void appldata_get_mem_data(void *data) mem_data->timestamp = get_clock(); mem_data->sync_count_2++; -#ifdef APPLDATA_DEBUG - appldata_debug_print(mem_data); -#endif } @@ -164,17 +136,7 @@ static struct appldata_ops ops = { */ static int __init appldata_mem_init(void) { - int rc; - - P_DEBUG("sizeof(mem) = %lu\n", sizeof(struct appldata_mem_data)); - - rc = appldata_register_ops(&ops); - if (rc != 0) { - P_ERROR("Error registering ops, rc = %i\n", rc); - } else { - P_DEBUG("%s-ops registered!\n", ops.name); - } - return rc; + return appldata_register_ops(&ops); } /* @@ -185,7 +147,6 @@ static int __init appldata_mem_init(void) static void __exit appldata_mem_exit(void) { appldata_unregister_ops(&ops); - P_DEBUG("%s-ops unregistered!\n", ops.name); } diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 4d834433600..3b746556e1a 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -21,9 +21,6 @@ #include "appldata.h" -#define MY_PRINT_NAME "appldata_net_sum" /* for debug messages, etc. */ - - /* * Network data * @@ -60,26 +57,6 @@ static struct appldata_net_sum_data { } __attribute__((packed)) appldata_net_sum_data; -static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) -{ - P_DEBUG("--- NET - RECORD ---\n"); - - P_DEBUG("nr_interfaces = %u\n", net_data->nr_interfaces); - P_DEBUG("rx_packets = %8lu\n", net_data->rx_packets); - P_DEBUG("tx_packets = %8lu\n", net_data->tx_packets); - P_DEBUG("rx_bytes = %8lu\n", net_data->rx_bytes); - P_DEBUG("tx_bytes = %8lu\n", net_data->tx_bytes); - P_DEBUG("rx_errors = %8lu\n", net_data->rx_errors); - P_DEBUG("tx_errors = %8lu\n", net_data->tx_errors); - P_DEBUG("rx_dropped = %8lu\n", net_data->rx_dropped); - P_DEBUG("tx_dropped = %8lu\n", net_data->tx_dropped); - P_DEBUG("collisions = %8lu\n", net_data->collisions); - - P_DEBUG("sync_count_1 = %u\n", net_data->sync_count_1); - P_DEBUG("sync_count_2 = %u\n", net_data->sync_count_2); - P_DEBUG("timestamp = %lX\n", net_data->timestamp); -} - /* * appldata_get_net_sum_data() * @@ -135,9 +112,6 @@ static void appldata_get_net_sum_data(void *data) net_data->timestamp = get_clock(); net_data->sync_count_2++; -#ifdef APPLDATA_DEBUG - appldata_print_debug(net_data); -#endif } @@ -159,17 +133,7 @@ static struct appldata_ops ops = { */ static int __init appldata_net_init(void) { - int rc; - - P_DEBUG("sizeof(net) = %lu\n", sizeof(struct appldata_net_sum_data)); - - rc = appldata_register_ops(&ops); - if (rc != 0) { - P_ERROR("Error registering ops, rc = %i\n", rc); - } else { - P_DEBUG("%s-ops registered!\n", ops.name); - } - return rc; + return appldata_register_ops(&ops); } /* @@ -180,7 +144,6 @@ static int __init appldata_net_init(void) static void __exit appldata_net_exit(void) { appldata_unregister_ops(&ops); - P_DEBUG("%s-ops unregistered!\n", ops.name); } diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 6b3eafe1045..eb44f9f8ab9 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -89,44 +89,6 @@ static struct appldata_ops ops = { }; -static inline void appldata_print_debug(struct appldata_os_data *os_data) -{ - int a0, a1, a2, i; - - P_DEBUG("--- OS - RECORD ---\n"); - P_DEBUG("nr_threads = %u\n", os_data->nr_threads); - P_DEBUG("nr_running = %u\n", os_data->nr_running); - P_DEBUG("nr_iowait = %u\n", os_data->nr_iowait); - P_DEBUG("avenrun(int) = %8x / %8x / %8x\n", os_data->avenrun[0], - os_data->avenrun[1], os_data->avenrun[2]); - a0 = os_data->avenrun[0]; - a1 = os_data->avenrun[1]; - a2 = os_data->avenrun[2]; - P_DEBUG("avenrun(float) = %d.%02d / %d.%02d / %d.%02d\n", - LOAD_INT(a0), LOAD_FRAC(a0), LOAD_INT(a1), LOAD_FRAC(a1), - LOAD_INT(a2), LOAD_FRAC(a2)); - - P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); - for (i = 0; i < os_data->nr_cpus; i++) { - P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " - "idle = %u, irq = %u, softirq = %u, iowait = %u, " - "steal = %u\n", - os_data->os_cpu[i].cpu_id, - os_data->os_cpu[i].per_cpu_user, - os_data->os_cpu[i].per_cpu_nice, - os_data->os_cpu[i].per_cpu_system, - os_data->os_cpu[i].per_cpu_idle, - os_data->os_cpu[i].per_cpu_irq, - os_data->os_cpu[i].per_cpu_softirq, - os_data->os_cpu[i].per_cpu_iowait, - os_data->os_cpu[i].per_cpu_steal); - } - - P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); - P_DEBUG("sync_count_2 = %u\n", os_data->sync_count_2); - P_DEBUG("timestamp = %lX\n", os_data->timestamp); -} - /* * appldata_get_os_data() * @@ -180,13 +142,10 @@ static void appldata_get_os_data(void *data) APPLDATA_START_INTERVAL_REC, (unsigned long) ops.data, new_size, ops.mod_lvl); - if (rc != 0) { + if (rc != 0) P_ERROR("os: START NEW DIAG 0xDC failed, " "return code: %d, new size = %i\n", rc, new_size); - P_INFO("os: stopping old record now\n"); - } else - P_INFO("os: new record size = %i\n", new_size); rc = appldata_diag(APPLDATA_RECORD_OS_ID, APPLDATA_STOP_REC, @@ -204,9 +163,6 @@ static void appldata_get_os_data(void *data) } os_data->timestamp = get_clock(); os_data->sync_count_2++; -#ifdef APPLDATA_DEBUG - appldata_print_debug(os_data); -#endif } @@ -227,12 +183,9 @@ static int __init appldata_os_init(void) rc = -ENOMEM; goto out; } - P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size, - sizeof(struct appldata_os_per_cpu)); appldata_os_data = kzalloc(max_size, GFP_DMA); if (appldata_os_data == NULL) { - P_ERROR("No memory for %s!\n", ops.name); rc = -ENOMEM; goto out; } @@ -240,17 +193,12 @@ static int __init appldata_os_init(void) appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, os_cpu); - P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); ops.data = appldata_os_data; ops.callback = &appldata_get_os_data; rc = appldata_register_ops(&ops); - if (rc != 0) { - P_ERROR("Error registering ops, rc = %i\n", rc); + if (rc != 0) kfree(appldata_os_data); - } else { - P_DEBUG("%s-ops registered!\n", ops.name); - } out: return rc; } @@ -264,7 +212,6 @@ static void __exit appldata_os_exit(void) { appldata_unregister_ops(&ops); kfree(appldata_os_data); - P_DEBUG("%s-ops unregistered!\n", ops.name); } -- GitLab From 2ca5b6e288d02503cba5a6d3409cb9a0600e01dd Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 14 Jul 2008 09:59:35 +0200 Subject: [PATCH 1802/2509] [S390] Cleanup monreader printk messages. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/monreader.c | 74 ++++------------------------------- 1 file changed, 7 insertions(+), 67 deletions(-) diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 1e1f50655bb..f0e4c96afbf 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -3,9 +3,8 @@ * * Character device driver for reading z/VM *MONITOR service records. * - * Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH. - * - * Author: Gerald Schaefer + * Copyright IBM Corp. 2004, 2008 + * Author: Gerald Schaefer */ #include @@ -18,12 +17,11 @@ #include #include #include +#include +#include #include #include #include -#include -#include - //#define MON_DEBUG /* Debug messages on/off */ @@ -152,10 +150,7 @@ static int mon_check_mca(struct mon_msg *monmsg) (mon_mca_end(monmsg) > mon_dcss_end) || (mon_mca_start(monmsg) < mon_dcss_start) || ((mon_mca_type(monmsg, 1) == 0) && (mon_mca_type(monmsg, 2) == 0))) - { - P_DEBUG("READ, IGNORED INVALID MCA\n\n"); return -EINVAL; - } return 0; } @@ -164,10 +159,6 @@ static int mon_send_reply(struct mon_msg *monmsg, { int rc; - P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = " - "0x%08X\n\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); - rc = iucv_message_reply(monpriv->path, &monmsg->msg, IUCV_IPRMDATA, NULL, 0); atomic_dec(&monpriv->msglim_count); @@ -202,15 +193,12 @@ static struct mon_private *mon_alloc_mem(void) struct mon_private *monpriv; monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); - if (!monpriv) { - P_ERROR("no memory for monpriv\n"); + if (!monpriv) return NULL; - } for (i = 0; i < MON_MSGLIM; i++) { monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg), GFP_KERNEL); if (!monpriv->msg_array[i]) { - P_ERROR("open, no memory for msg_array\n"); mon_free_mem(monpriv); return NULL; } @@ -218,41 +206,10 @@ static struct mon_private *mon_alloc_mem(void) return monpriv; } -static inline void mon_read_debug(struct mon_msg *monmsg, - struct mon_private *monpriv) -{ -#ifdef MON_DEBUG - u8 msg_type[2], mca_type; - unsigned long records_len; - - records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1; - - memcpy(msg_type, &monmsg->msg.class, 2); - EBCASC(msg_type, 2); - mca_type = mon_mca_type(monmsg, 0); - EBCASC(&mca_type, 1); - - P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n", - monpriv->read_index, monpriv->write_index); - P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); - P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n", - msg_type[0], msg_type[1], mca_type ? mca_type : 'X', - mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2)); - P_DEBUG("read, MCA: start = 0x%lX, end = 0x%lX\n", - mon_mca_start(monmsg), mon_mca_end(monmsg)); - P_DEBUG("read, REC: start = 0x%X, end = 0x%X, len = %lu\n\n", - mon_rec_start(monmsg), mon_rec_end(monmsg), records_len); - if (mon_mca_size(monmsg) > 12) - P_DEBUG("READ, MORE THAN ONE MCA\n\n"); -#endif -} - static inline void mon_next_mca(struct mon_msg *monmsg) { if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12)) return; - P_DEBUG("READ, NEXT MCA\n\n"); monmsg->mca_offset += 12; monmsg->pos = 0; } @@ -269,7 +226,6 @@ static struct mon_msg *mon_next_message(struct mon_private *monpriv) monmsg->msglim_reached = 0; monmsg->pos = 0; monmsg->mca_offset = 0; - P_WARNING("read, message limit reached\n"); monpriv->read_index = (monpriv->read_index + 1) % MON_MSGLIM; atomic_dec(&monpriv->read_ready); @@ -286,10 +242,6 @@ static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) { struct mon_private *monpriv = path->private; - P_DEBUG("IUCV connection completed\n"); - P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = " - "0x%02X, Sample = 0x%02X\n", - ipuser[0], ipuser[1], ipuser[2]); atomic_set(&monpriv->iucv_connected, 1); wake_up(&mon_conn_wait_queue); } @@ -310,7 +262,6 @@ static void mon_iucv_message_pending(struct iucv_path *path, { struct mon_private *monpriv = path->private; - P_DEBUG("IUCV message pending\n"); memcpy(&monpriv->msg_array[monpriv->write_index]->msg, msg, sizeof(*msg)); if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) { @@ -375,7 +326,6 @@ static int mon_open(struct inode *inode, struct file *filp) rc = -EIO; goto out_path; } - P_INFO("open, established connection to *MONITOR service\n\n"); filp->private_data = monpriv; return nonseekable_open(inode, filp); @@ -400,8 +350,6 @@ static int mon_close(struct inode *inode, struct file *filp) rc = iucv_path_sever(monpriv->path, user_data_sever); if (rc) P_ERROR("close, iucv_sever failed with rc = %i\n", rc); - else - P_INFO("close, terminated connection to *MONITOR service\n"); atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); @@ -442,10 +390,8 @@ static ssize_t mon_read(struct file *filp, char __user *data, monmsg = monpriv->msg_array[monpriv->read_index]; } - if (!monmsg->pos) { + if (!monmsg->pos) monmsg->pos = mon_mca_start(monmsg) + monmsg->mca_offset; - mon_read_debug(monmsg, monpriv); - } if (mon_check_mca(monmsg)) goto reply; @@ -531,7 +477,6 @@ static int __init mon_init(void) P_ERROR("failed to register with iucv driver\n"); return rc; } - P_INFO("open, registered with IUCV\n"); rc = segment_type(mon_dcss_name); if (rc < 0) { @@ -555,13 +500,8 @@ static int __init mon_init(void) dcss_mkname(mon_dcss_name, &user_data_connect[8]); rc = misc_register(&mon_dev); - if (rc < 0 ) { - P_ERROR("misc_register failed, rc = %i\n", rc); + if (rc < 0 ) goto out; - } - P_INFO("Loaded segment %s from %p to %p, size = %lu Byte\n", - mon_dcss_name, (void *) mon_dcss_start, (void *) mon_dcss_end, - mon_dcss_end - mon_dcss_start + 1); return 0; out: -- GitLab From 21b21fc4f4b03361ceec0c7eb6b7b0557d4ffe86 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 14 Jul 2008 09:59:36 +0200 Subject: [PATCH 1803/2509] [S390] Cleanup s390 debug feature print messages. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/debug.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index c93d1296cc0..d80fcd4a7fe 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -1079,7 +1079,6 @@ __init debug_init(void) s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); mutex_lock(&debug_mutex); debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); - printk(KERN_INFO "debug: Initialization complete\n"); initialized = 1; mutex_unlock(&debug_mutex); @@ -1193,7 +1192,6 @@ debug_get_uint(char *buf) for(; isspace(*buf); buf++); rc = simple_strtoul(buf, &buf, 10); if(*buf){ - printk("debug: no integer specified!\n"); rc = -EINVAL; } return rc; @@ -1340,19 +1338,12 @@ static void debug_flush(debug_info_t* id, int area) memset(id->areas[i][j], 0, PAGE_SIZE); } } - printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); } else if(area >= 0 && area < id->nr_areas) { id->active_entries[area] = 0; id->active_pages[area] = 0; for(i = 0; i < id->pages_per_area; i++) { memset(id->areas[area][i],0,PAGE_SIZE); } - printk(KERN_INFO "debug: %s: area %i has been flushed\n", - id->name, area); - } else { - printk(KERN_INFO - "debug: %s: area %i cannot be flushed (range: %i - %i)\n", - id->name, area, 0, id->nr_areas-1); } spin_unlock_irqrestore(&id->lock,flags); } -- GitLab From 2f6f2521bcfff108e02d97e3a326f995996ce95f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:37 +0200 Subject: [PATCH 1804/2509] [S390] Cleanup vmlogrdr printk messages. The message descriptions are still missing though .. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/vmlogrdr.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 2c2428cc05d..a246bc73ae6 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -216,9 +216,7 @@ static int vmlogrdr_get_recording_class_AB(void) char *tail; int len,i; - printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); - printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); len = strnlen(cp_response,sizeof(cp_response)); // now the parsing tail=strnchr(cp_response,len,'='); @@ -268,11 +266,7 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, logptr->recording_name, qid_string); - printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", - cp_command); cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); - printk (KERN_DEBUG "vmlogrdr: recording response: %s", - cp_response); } memset(cp_command, 0x00, sizeof(cp_command)); @@ -282,10 +276,7 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, onoff, qid_string); - printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); - printk (KERN_DEBUG "vmlogrdr: recording response: %s", - cp_response); /* The recording command will usually answer with 'Command complete' * on success, but when the specific service was never connected * before then there might be an additional informational message @@ -567,10 +558,7 @@ static ssize_t vmlogrdr_purge_store(struct device * dev, "RECORDING %s PURGE ", priv->recording_name); - printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); - printk (KERN_DEBUG "vmlogrdr: recording response: %s", - cp_response); return count; } @@ -682,28 +670,20 @@ static int vmlogrdr_register_driver(void) /* Register with iucv driver */ ret = iucv_register(&vmlogrdr_iucv_handler, 1); - if (ret) { - printk (KERN_ERR "vmlogrdr: failed to register with " - "iucv driver\n"); + if (ret) goto out; - } ret = driver_register(&vmlogrdr_driver); - if (ret) { - printk(KERN_ERR "vmlogrdr: failed to register driver.\n"); + if (ret) goto out_iucv; - } ret = driver_create_file(&vmlogrdr_driver, &driver_attr_recording_status); - if (ret) { - printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n"); + if (ret) goto out_driver; - } vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { - printk(KERN_ERR "vmlogrdr: failed to create class.\n"); ret = PTR_ERR(vmlogrdr_class); vmlogrdr_class = NULL; goto out_attr; @@ -871,12 +851,10 @@ static int __init vmlogrdr_init(void) rc = vmlogrdr_register_cdev(dev); if (rc) goto cleanup; - printk (KERN_INFO "vmlogrdr: driver loaded\n"); return 0; cleanup: vmlogrdr_cleanup(); - printk (KERN_ERR "vmlogrdr: driver not loaded.\n"); return rc; } @@ -884,7 +862,6 @@ cleanup: static void __exit vmlogrdr_exit(void) { vmlogrdr_cleanup(); - printk (KERN_INFO "vmlogrdr: driver unloaded\n"); return; } -- GitLab From 2a062ab483f5afd764fb20631ee960672946a4be Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 14 Jul 2008 09:59:38 +0200 Subject: [PATCH 1805/2509] [S390] Cleanup zfcp dumper printk messages. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/zcore.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index bbbd14e9d48..047dd92ae80 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -223,12 +223,10 @@ static int __init init_cpu_info(enum arch_id arch) /* get info for boot cpu from lowcore, stored in the HSA */ sa = kmalloc(sizeof(*sa), GFP_KERNEL); - if (!sa) { - ERROR_MSG("kmalloc failed: %s: %i\n",__func__, __LINE__); + if (!sa) return -ENOMEM; - } if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) { - ERROR_MSG("could not copy from HSA\n"); + TRACE("could not copy from HSA\n"); kfree(sa); return -EIO; } @@ -511,6 +509,8 @@ static void __init set_s390x_lc_mask(union save_area *map) */ static int __init sys_info_init(enum arch_id arch) { + int rc; + switch (arch) { case ARCH_S390X: MSG("DETECTED 'S390X (64 bit) OS'\n"); @@ -529,10 +529,9 @@ static int __init sys_info_init(enum arch_id arch) return -EINVAL; } sys_info.arch = arch; - if (init_cpu_info(arch)) { - ERROR_MSG("get cpu info failed\n"); - return -ENOMEM; - } + rc = init_cpu_info(arch); + if (rc) + return rc; sys_info.mem_size = real_memory_size; return 0; @@ -544,12 +543,12 @@ static int __init check_sdias(void) rc = sclp_sdias_blk_count(); if (rc < 0) { - ERROR_MSG("Could not determine HSA size\n"); + TRACE("Could not determine HSA size\n"); return rc; } act_hsa_size = (rc - 1) * PAGE_SIZE; if (act_hsa_size < ZFCPDUMP_HSA_SIZE) { - ERROR_MSG("HSA size too small: %i\n", act_hsa_size); + TRACE("HSA size too small: %i\n", act_hsa_size); return -EINVAL; } return 0; @@ -590,16 +589,12 @@ static int __init zcore_init(void) goto fail; rc = check_sdias(); - if (rc) { - ERROR_MSG("Dump initialization failed\n"); + if (rc) goto fail; - } rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1); - if (rc) { - ERROR_MSG("sdial memcpy for arch id failed\n"); + if (rc) goto fail; - } #ifndef __s390x__ if (arch == ARCH_S390X) { @@ -610,10 +605,8 @@ static int __init zcore_init(void) #endif rc = sys_info_init(arch); - if (rc) { - ERROR_MSG("arch init failed\n"); + if (rc) goto fail; - } zcore_header_init(arch, &zcore_header); -- GitLab From ded77fb4dfcd6f84e564ddd9458208bf5b691c7f Mon Sep 17 00:00:00 2001 From: Hongjie Yang Date: Mon, 14 Jul 2008 09:59:39 +0200 Subject: [PATCH 1806/2509] [S390] Cleanup dcssblk printk messages. Signed-off-by: Hongjie Yang Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/block/dcssblk.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index bb52d2fbac1..01fcdd91b84 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -167,10 +167,8 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch struct dcssblk_dev_info *dev_info; int rc; - if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) { - PRINT_WARN("Invalid value, must be 0 or 1\n"); + if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) return -EINVAL; - } down_write(&dcssblk_devices_sem); dev_info = container_of(dev, struct dcssblk_dev_info, dev); if (atomic_read(&dev_info->use_count)) { @@ -215,7 +213,6 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch set_disk_ro(dev_info->gd, 0); } } else { - PRINT_WARN("Invalid value, must be 0 or 1\n"); rc = -EINVAL; goto out; } @@ -258,10 +255,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char { struct dcssblk_dev_info *dev_info; - if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) { - PRINT_WARN("Invalid value, must be 0 or 1\n"); + if ((count > 1) && (inbuf[1] != '\n') && (inbuf[1] != '\0')) return -EINVAL; - } dev_info = container_of(dev, struct dcssblk_dev_info, dev); down_write(&dcssblk_devices_sem); @@ -289,7 +284,6 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char } } else { up_write(&dcssblk_devices_sem); - PRINT_WARN("Invalid value, must be 0 or 1\n"); return -EINVAL; } up_write(&dcssblk_devices_sem); @@ -441,7 +435,6 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char goto out; unregister_dev: - PRINT_ERR("device_create_file() failed!\n"); list_del(&dev_info->lh); blk_cleanup_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; @@ -702,10 +695,8 @@ dcssblk_check_params(void) static void __exit dcssblk_exit(void) { - PRINT_DEBUG("DCSSBLOCK EXIT...\n"); s390_root_dev_unregister(dcssblk_root_dev); unregister_blkdev(dcssblk_major, DCSSBLK_NAME); - PRINT_DEBUG("...finished!\n"); } static int __init @@ -713,27 +704,21 @@ dcssblk_init(void) { int rc; - PRINT_DEBUG("DCSSBLOCK INIT...\n"); dcssblk_root_dev = s390_root_dev_register("dcssblk"); - if (IS_ERR(dcssblk_root_dev)) { - PRINT_ERR("device_register() failed!\n"); + if (IS_ERR(dcssblk_root_dev)) return PTR_ERR(dcssblk_root_dev); - } rc = device_create_file(dcssblk_root_dev, &dev_attr_add); if (rc) { - PRINT_ERR("device_create_file(add) failed!\n"); s390_root_dev_unregister(dcssblk_root_dev); return rc; } rc = device_create_file(dcssblk_root_dev, &dev_attr_remove); if (rc) { - PRINT_ERR("device_create_file(remove) failed!\n"); s390_root_dev_unregister(dcssblk_root_dev); return rc; } rc = register_blkdev(0, DCSSBLK_NAME); if (rc < 0) { - PRINT_ERR("Can't get dynamic major!\n"); s390_root_dev_unregister(dcssblk_root_dev); return rc; } @@ -742,7 +727,6 @@ dcssblk_init(void) dcssblk_check_params(); - PRINT_DEBUG("...finished!\n"); return 0; } -- GitLab From 0d130066801af8f0a0ea8c70c9c7374c51fd1a92 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:40 +0200 Subject: [PATCH 1807/2509] [S390] Cleanup vmwatch printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/vmwatchdog.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index 19f8389291b..56b3eab019c 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c @@ -92,23 +92,15 @@ static int vmwdt_keepalive(void) func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init; ret = __diag288(func, vmwdt_interval, ebc_cmd, len); + WARN_ON(ret != 0); kfree(ebc_cmd); - - if (ret) { - printk(KERN_WARNING "%s: problem setting interval %d, " - "cmd %s\n", __func__, vmwdt_interval, - vmwdt_cmd); - } return ret; } static int vmwdt_disable(void) { int ret = __diag288(wdt_cancel, 0, "", 0); - if (ret) { - printk(KERN_WARNING "%s: problem disabling watchdog\n", - __func__); - } + WARN_ON(ret != 0); return ret; } @@ -121,10 +113,8 @@ static int __init vmwdt_probe(void) static char __initdata ebc_begin[] = { 194, 197, 199, 201, 213 }; - if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) { - printk(KERN_INFO "z/VM watchdog not available\n"); + if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) return -EINVAL; - } return vmwdt_disable(); } -- GitLab From 5532bd0f8591a5f61cfe903646e1f55e047bae90 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 14 Jul 2008 09:59:41 +0200 Subject: [PATCH 1808/2509] [S390] Cleanup kprobes printk messages. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/kprobes.c | 4 +--- arch/s390/kernel/machine_kexec.c | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index ed04d1372d5..288ad490a6d 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -41,10 +41,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) if (is_prohibited_opcode((kprobe_opcode_t *) p->addr)) return -EINVAL; - if ((unsigned long)p->addr & 0x01) { - printk("Attempt to register kprobe at an unaligned address\n"); + if ((unsigned long)p->addr & 0x01) return -EINVAL; - } /* Use the get_insn_slot() facility for correctness */ if (!(p->ainsn.insn = get_insn_slot())) diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 3c77dd36994..131d7ee8b41 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -52,7 +52,6 @@ void machine_kexec_cleanup(struct kimage *image) void machine_shutdown(void) { - printk(KERN_INFO "kexec: machine_shutdown called\n"); } void machine_kexec(struct kimage *image) -- GitLab From 6b648063eb51e2620774ddaebef4e07f2f6f4ae7 Mon Sep 17 00:00:00 2001 From: "Klaus-D. Wacker" Date: Mon, 14 Jul 2008 09:59:42 +0200 Subject: [PATCH 1809/2509] [S390] Cleanup lcs printk messages. Cc: Jeff Garzik Signed-off-by: Klaus-D. Wacker Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/net/lcs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 586cca21da9..6de28385b35 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1762,7 +1762,7 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) netif_carrier_off(card->dev); break; default: - PRINT_INFO("UNRECOGNIZED LGW COMMAND\n"); + LCS_DBF_TEXT(5, trace, "noLGWcmd"); break; } } else @@ -2043,13 +2043,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) LCS_DBF_TEXT(2, setup, "add_dev"); card = lcs_alloc_card(); if (!card) { - PRINT_ERR("Allocation of lcs card failed\n"); + LCS_DBF_TEXT_(2, setup, " rc%d", -ENOMEM); put_device(&ccwgdev->dev); return -ENOMEM; } ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group); if (ret) { - PRINT_ERR("Creating attributes failed"); lcs_free_card(card); put_device(&ccwgdev->dev); return ret; @@ -2141,7 +2140,6 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) default: LCS_DBF_TEXT(3, setup, "errinit"); PRINT_ERR("LCS: Initialization failed\n"); - PRINT_ERR("LCS: No device found!\n"); goto out; } if (!dev) @@ -2270,7 +2268,6 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev) if (!card) return; - PRINT_INFO("Removing lcs group device ....\n"); LCS_DBF_TEXT(3, setup, "remdev"); LCS_DBF_HEX(3, setup, &card, sizeof(void*)); if (ccwgdev->state == CCWGROUP_ONLINE) { -- GitLab From a44008f2372684bacfab03de5039f68b613c5b53 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 14 Jul 2008 09:59:43 +0200 Subject: [PATCH 1810/2509] [S390] Cleanup vmcp printk messages. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/vmcp.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index af616aeaa93..401ea84b305 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -192,27 +192,23 @@ static int __init vmcp_init(void) PRINT_WARN("z/VM CP interface is only available under z/VM\n"); return -ENODEV; } + vmcp_debug = debug_register("vmcp", 1, 1, 240); - if (!vmcp_debug) { - PRINT_ERR("z/VM CP interface not loaded. Could not register " - "debug feature\n"); + if (!vmcp_debug) return -ENOMEM; - } + ret = debug_register_view(vmcp_debug, &debug_hex_ascii_view); if (ret) { - PRINT_ERR("z/VM CP interface not loaded. Could not register " - "debug feature view. Error code: %d\n", ret); debug_unregister(vmcp_debug); return ret; } + ret = misc_register(&vmcp_dev); if (ret) { - PRINT_ERR("z/VM CP interface not loaded. Could not register " - "misc device. Error code: %d\n", ret); debug_unregister(vmcp_debug); return ret; } - PRINT_INFO("z/VM CP interface loaded\n"); + return 0; } @@ -220,7 +216,6 @@ static void __exit vmcp_exit(void) { misc_deregister(&vmcp_dev); debug_unregister(vmcp_debug); - PRINT_INFO("z/VM CP interface unloaded.\n"); } module_init(vmcp_init); -- GitLab From 1d030370f09036e8dcb3cc40915f3f9cf92bb54c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:44 +0200 Subject: [PATCH 1811/2509] [S390] Remove P390 support. Most likely it is broken anyway because of the changes in memory detection. Since we can't test it and there are probably better ways that using a P390 card, remove support for it. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 4 ---- arch/s390/kernel/setup.c | 6 ------ drivers/s390/char/con3215.c | 9 +-------- drivers/s390/char/sclp.c | 2 -- drivers/s390/net/cu3088.c | 2 -- drivers/s390/net/cu3088.h | 3 --- include/asm-s390/setup.h | 2 -- 7 files changed, 1 insertion(+), 27 deletions(-) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 4c0ec7b46e3..2a2ca268b1d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -183,10 +183,6 @@ static noinline __init void detect_machine_type(void) if (cpuinfo->cpu_id.version == 0xff) machine_flags |= MACHINE_FLAG_VM; - /* Running on a P/390 ? */ - if (cpuinfo->cpu_id.machine == 0x7490) - machine_flags |= MACHINE_FLAG_P390; - /* Running under KVM ? */ if (cpuinfo->cpu_id.version == 0xfe) machine_flags |= MACHINE_FLAG_KVM; diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 9c92407f625..b358e18273b 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -205,12 +205,6 @@ static void __init conmode_default(void) SET_CONSOLE_SCLP; #endif } - } else if (MACHINE_IS_P390) { -#if defined(CONFIG_TN3215_CONSOLE) - SET_CONSOLE_3215; -#elif defined(CONFIG_TN3270_CONSOLE) - SET_CONSOLE_3270; -#endif } else { #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 4b632504c65..d3ec9b55ab3 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -373,7 +373,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) struct raw3215_req *req; struct tty_struct *tty; int cstat, dstat; - int count, slen; + int count; raw = cdev->dev.driver_data; req = (struct raw3215_req *) intparm; @@ -390,8 +390,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) break; /* Attention interrupt, someone hit the enter key */ raw3215_mk_read_req(raw); - if (MACHINE_IS_P390) - memset(raw->inbuf, 0, RAW3215_INBUF_SIZE); tasklet_schedule(&raw->tasklet); break; case 0x08: @@ -414,11 +412,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) tty = raw->tty; count = 160 - req->residual; - if (MACHINE_IS_P390) { - slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE); - if (count > slen) - count = slen; - } else EBCASC(raw->inbuf, count); cchar = ctrlchar_handle(raw->inbuf, count, tty); switch (cchar & CTRLCHAR_MASK) { diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index fb97cf5ee67..3c8b25e6c34 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -883,8 +883,6 @@ sclp_init(void) unsigned long flags; int rc; - if (!MACHINE_HAS_SCLP) - return -ENODEV; spin_lock_irqsave(&sclp_lock, flags); /* Check for previous or running initialization */ if (sclp_init_state != sclp_init_state_uninitialized) { diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c index 8e7697305a4..f4a32375c03 100644 --- a/drivers/s390/net/cu3088.c +++ b/drivers/s390/net/cu3088.c @@ -36,7 +36,6 @@ const char *cu3088_type[] = { "CTC/A", "ESCON channel", "FICON channel", - "P390 LCS card", "OSA LCS card", "CLAW channel device", "unknown channel type", @@ -49,7 +48,6 @@ static struct ccw_device_id cu3088_ids[] = { { CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel }, { CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon }, { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, - { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 }, { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw }, { /* end of list */ } diff --git a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h index 1753661f702..d8558a7105a 100644 --- a/drivers/s390/net/cu3088.h +++ b/drivers/s390/net/cu3088.h @@ -17,9 +17,6 @@ enum channel_types { /* Device is a FICON channel */ channel_type_ficon, - /* Device is a P390 LCS card */ - channel_type_p390, - /* Device is a OSA2 card */ channel_type_osa2, diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index 80747ba6ef8..f09ee3f7297 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -65,7 +65,6 @@ 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) @@ -101,7 +100,6 @@ extern unsigned long machine_flags; #define MACHINE_HAS_PFMF (machine_flags & MACHINE_FLAG_PFMF) #endif /* __s390x__ */ -#define MACHINE_HAS_SCLP (!MACHINE_IS_P390) #define ZFCPDUMP_HSA_SIZE (32UL<<20) /* -- GitLab From 095761d28ae43eae7d4504d49b0b952cf02b0188 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:45 +0200 Subject: [PATCH 1812/2509] [S390] sclp_tty: remove ioctl interface. After all we came to the conclusion that this interface doesn't make any sense. Besides that the ioctl number used was never registered, the header file isn't exported, and we doubt there is even a single user. So remove this interface, since it eases maintenance. Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky --- drivers/s390/char/sclp_con.c | 1 + drivers/s390/char/sclp_tty.c | 217 ++++------------------------------- drivers/s390/char/sclp_tty.h | 53 --------- 3 files changed, 23 insertions(+), 248 deletions(-) diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c index 0ddf1b7c00d..7e619c534bf 100644 --- a/drivers/s390/char/sclp_con.c +++ b/drivers/s390/char/sclp_con.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "sclp.h" diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index d3b1957cd2f..bcf691af533 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -57,19 +57,11 @@ static unsigned short int sclp_tty_chars_count; struct tty_driver *sclp_tty_driver; -static struct sclp_ioctls sclp_ioctls; -static struct sclp_ioctls sclp_ioctls_init = -{ - 8, /* 1 hor. tab. = 8 spaces */ - 0, /* no echo of input by this driver */ - 80, /* 80 characters/line */ - 1, /* write after 1/10 s without final new line */ - MAX_KMEM_PAGES, /* quick fix: avoid __alloc_pages */ - MAX_KMEM_PAGES, /* take 32/64 pages from kernel memory, */ - 0, /* do not convert to lower case */ - 0x6c /* to seprate upper and lower case */ - /* ('%' in EBCDIC) */ -}; +static int sclp_tty_tolower; +static int sclp_tty_columns = 80; + +#define SPACES_PER_TAB 8 +#define CASE_DELIMITER 0x6c /* to separate upper and lower case (% in EBCDIC) */ /* This routine is called whenever we try to open a SCLP terminal. */ static int @@ -90,136 +82,6 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp) sclp_tty = NULL; } -/* execute commands to control the i/o behaviour of the SCLP tty at runtime */ -static int -sclp_tty_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - unsigned long flags; - unsigned int obuf; - int check; - int rc; - - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - rc = 0; - check = 0; - switch (cmd) { - case TIOCSCLPSHTAB: - /* set width of horizontal tab */ - if (get_user(sclp_ioctls.htab, (unsigned short __user *) arg)) - rc = -EFAULT; - else - check = 1; - break; - case TIOCSCLPGHTAB: - /* get width of horizontal tab */ - if (put_user(sclp_ioctls.htab, (unsigned short __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSECHO: - /* enable/disable echo of input */ - if (get_user(sclp_ioctls.echo, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPGECHO: - /* Is echo of input enabled ? */ - if (put_user(sclp_ioctls.echo, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSCOLS: - /* set number of columns for output */ - if (get_user(sclp_ioctls.columns, (unsigned short __user *) arg)) - rc = -EFAULT; - else - check = 1; - break; - case TIOCSCLPGCOLS: - /* get number of columns for output */ - if (put_user(sclp_ioctls.columns, (unsigned short __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSNL: - /* enable/disable writing without final new line character */ - if (get_user(sclp_ioctls.final_nl, (signed char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPGNL: - /* Is writing without final new line character enabled ? */ - if (put_user(sclp_ioctls.final_nl, (signed char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSOBUF: - /* - * set the maximum buffers size for output, will be rounded - * up to next 4kB boundary and stored as number of SCCBs - * (4kB Buffers) limitation: 256 x 4kB - */ - if (get_user(obuf, (unsigned int __user *) arg) == 0) { - if (obuf & 0xFFF) - sclp_ioctls.max_sccb = (obuf >> 12) + 1; - else - sclp_ioctls.max_sccb = (obuf >> 12); - } else - rc = -EFAULT; - break; - case TIOCSCLPGOBUF: - /* get the maximum buffers size for output */ - obuf = sclp_ioctls.max_sccb << 12; - if (put_user(obuf, (unsigned int __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPGKBUF: - /* get the number of buffers got from kernel at startup */ - if (put_user(sclp_ioctls.kmem_sccb, (unsigned short __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSCASE: - /* enable/disable conversion from upper to lower case */ - if (get_user(sclp_ioctls.tolower, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPGCASE: - /* Is conversion from upper to lower case of input enabled? */ - if (put_user(sclp_ioctls.tolower, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSDELIM: - /* - * set special character used for separating upper and - * lower case, 0x00 disables this feature - */ - if (get_user(sclp_ioctls.delim, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPGDELIM: - /* - * get special character used for separating upper and - * lower case, 0x00 disables this feature - */ - if (put_user(sclp_ioctls.delim, (unsigned char __user *) arg)) - rc = -EFAULT; - break; - case TIOCSCLPSINIT: - /* set initial (default) sclp ioctls */ - sclp_ioctls = sclp_ioctls_init; - check = 1; - break; - default: - rc = -ENOIOCTLCMD; - break; - } - if (check) { - spin_lock_irqsave(&sclp_tty_lock, flags); - if (sclp_ttybuf != NULL) { - sclp_set_htab(sclp_ttybuf, sclp_ioctls.htab); - sclp_set_columns(sclp_ttybuf, sclp_ioctls.columns); - } - spin_unlock_irqrestore(&sclp_tty_lock, flags); - } - return rc; -} - /* * This routine returns the numbers of characters the tty driver * will accept for queuing to be written. This number is subject @@ -339,9 +201,8 @@ sclp_tty_write_string(const unsigned char *str, int count) } page = sclp_tty_pages.next; list_del((struct list_head *) page); - sclp_ttybuf = sclp_make_buffer(page, - sclp_ioctls.columns, - sclp_ioctls.htab); + sclp_ttybuf = sclp_make_buffer(page, sclp_tty_columns, + SPACES_PER_TAB); } /* try to write the string to the current output buffer */ written = sclp_write(sclp_ttybuf, str, count); @@ -361,25 +222,13 @@ sclp_tty_write_string(const unsigned char *str, int count) count -= written; } while (count > 0); /* Setup timer to output current console buffer after 1/10 second */ - if (sclp_ioctls.final_nl) { - if (sclp_ttybuf != NULL && - sclp_chars_in_buffer(sclp_ttybuf) != 0 && - !timer_pending(&sclp_tty_timer)) { - init_timer(&sclp_tty_timer); - sclp_tty_timer.function = sclp_tty_timeout; - sclp_tty_timer.data = 0UL; - sclp_tty_timer.expires = jiffies + HZ/10; - add_timer(&sclp_tty_timer); - } - } else { - if (sclp_ttybuf != NULL && - sclp_chars_in_buffer(sclp_ttybuf) != 0) { - buf = sclp_ttybuf; - sclp_ttybuf = NULL; - spin_unlock_irqrestore(&sclp_tty_lock, flags); - __sclp_ttybuf_emit(buf); - spin_lock_irqsave(&sclp_tty_lock, flags); - } + if (sclp_ttybuf && sclp_chars_in_buffer(sclp_ttybuf) && + !timer_pending(&sclp_tty_timer)) { + init_timer(&sclp_tty_timer); + sclp_tty_timer.function = sclp_tty_timeout; + sclp_tty_timer.data = 0UL; + sclp_tty_timer.expires = jiffies + HZ/10; + add_timer(&sclp_tty_timer); } spin_unlock_irqrestore(&sclp_tty_lock, flags); } @@ -515,9 +364,7 @@ sclp_tty_input(unsigned char* buf, unsigned int count) * modifiy original string, * returns length of resulting string */ -static int -sclp_switch_cases(unsigned char *buf, int count, - unsigned char delim, int tolower) +static int sclp_switch_cases(unsigned char *buf, int count) { unsigned char *ip, *op; int toggle; @@ -527,9 +374,9 @@ sclp_switch_cases(unsigned char *buf, int count, ip = op = buf; while (count-- > 0) { /* compare with special character */ - if (*ip == delim) { + if (*ip == CASE_DELIMITER) { /* followed by another special character? */ - if (count && ip[1] == delim) { + if (count && ip[1] == CASE_DELIMITER) { /* * ... then put a single copy of the special * character to the output string @@ -548,7 +395,7 @@ sclp_switch_cases(unsigned char *buf, int count, /* not the special character */ if (toggle) /* but case switching is on */ - if (tolower) + if (sclp_tty_tolower) /* switch to uppercase */ *op++ = _ebc_toupper[(int) *ip++]; else @@ -568,30 +415,12 @@ sclp_get_input(unsigned char *start, unsigned char *end) int count; count = end - start; - /* - * if set in ioctl convert EBCDIC to lower case - * (modify original input in SCCB) - */ - if (sclp_ioctls.tolower) + if (sclp_tty_tolower) EBC_TOLOWER(start, count); - - /* - * if set in ioctl find out characters in lower or upper case - * (depends on current case) separated by a special character, - * works on EBCDIC - */ - if (sclp_ioctls.delim) - count = sclp_switch_cases(start, count, - sclp_ioctls.delim, - sclp_ioctls.tolower); - + count = sclp_switch_cases(start, count); /* convert EBCDIC to ASCII (modify original input in SCCB) */ sclp_ebcasc_str(start, count); - /* if set in ioctl write operators input to console */ - if (sclp_ioctls.echo) - sclp_tty_write(sclp_tty, start, count); - /* transfer input to high level driver */ sclp_tty_input(start, count); } @@ -715,7 +544,6 @@ static const struct tty_operations sclp_ops = { .write_room = sclp_tty_write_room, .chars_in_buffer = sclp_tty_chars_in_buffer, .flush_buffer = sclp_tty_flush_buffer, - .ioctl = sclp_tty_ioctl, }; static int __init @@ -758,11 +586,10 @@ sclp_tty_init(void) * save 4 characters for the CPU number * written at start of each line by VM/CP */ - sclp_ioctls_init.columns = 76; + sclp_tty_columns = 76; /* case input lines to lowercase */ - sclp_ioctls_init.tolower = 1; + sclp_tty_tolower = 1; } - sclp_ioctls = sclp_ioctls_init; sclp_tty_chars_count = 0; sclp_tty = NULL; diff --git a/drivers/s390/char/sclp_tty.h b/drivers/s390/char/sclp_tty.h index 0ce2c1fc534..4b965b22fec 100644 --- a/drivers/s390/char/sclp_tty.h +++ b/drivers/s390/char/sclp_tty.h @@ -11,61 +11,8 @@ #ifndef __SCLP_TTY_H__ #define __SCLP_TTY_H__ -#include -#include #include -/* This is the type of data structures storing sclp ioctl setting. */ -struct sclp_ioctls { - unsigned short htab; - unsigned char echo; - unsigned short columns; - unsigned char final_nl; - unsigned short max_sccb; - unsigned short kmem_sccb; /* can't be modified at run time */ - unsigned char tolower; - unsigned char delim; -}; - -/* must be unique, FIXME: must be added in Documentation/ioctl_number.txt */ -#define SCLP_IOCTL_LETTER 'B' - -/* set width of horizontal tabulator */ -#define TIOCSCLPSHTAB _IOW(SCLP_IOCTL_LETTER, 0, unsigned short) -/* enable/disable echo of input (independent from line discipline) */ -#define TIOCSCLPSECHO _IOW(SCLP_IOCTL_LETTER, 1, unsigned char) -/* set number of colums for output */ -#define TIOCSCLPSCOLS _IOW(SCLP_IOCTL_LETTER, 2, unsigned short) -/* enable/disable writing without final new line character */ -#define TIOCSCLPSNL _IOW(SCLP_IOCTL_LETTER, 4, signed char) -/* set the maximum buffers size for output, rounded up to next 4kB boundary */ -#define TIOCSCLPSOBUF _IOW(SCLP_IOCTL_LETTER, 5, unsigned short) -/* set initial (default) sclp ioctls */ -#define TIOCSCLPSINIT _IO(SCLP_IOCTL_LETTER, 6) -/* enable/disable conversion from upper to lower case of input */ -#define TIOCSCLPSCASE _IOW(SCLP_IOCTL_LETTER, 7, unsigned char) -/* set special character used for separating upper and lower case, */ -/* 0x00 disables this feature */ -#define TIOCSCLPSDELIM _IOW(SCLP_IOCTL_LETTER, 9, unsigned char) - -/* get width of horizontal tabulator */ -#define TIOCSCLPGHTAB _IOR(SCLP_IOCTL_LETTER, 10, unsigned short) -/* Is echo of input enabled ? (independent from line discipline) */ -#define TIOCSCLPGECHO _IOR(SCLP_IOCTL_LETTER, 11, unsigned char) -/* get number of colums for output */ -#define TIOCSCLPGCOLS _IOR(SCLP_IOCTL_LETTER, 12, unsigned short) -/* Is writing without final new line character enabled ? */ -#define TIOCSCLPGNL _IOR(SCLP_IOCTL_LETTER, 14, signed char) -/* get the maximum buffers size for output */ -#define TIOCSCLPGOBUF _IOR(SCLP_IOCTL_LETTER, 15, unsigned short) -/* Is conversion from upper to lower case of input enabled ? */ -#define TIOCSCLPGCASE _IOR(SCLP_IOCTL_LETTER, 17, unsigned char) -/* get special character used for separating upper and lower case, */ -/* 0x00 disables this feature */ -#define TIOCSCLPGDELIM _IOR(SCLP_IOCTL_LETTER, 19, unsigned char) -/* get the number of buffers/pages got from kernel at startup */ -#define TIOCSCLPGKBUF _IOR(SCLP_IOCTL_LETTER, 20, unsigned short) - extern struct tty_driver *sclp_tty_driver; #endif /* __SCLP_TTY_H__ */ -- GitLab From 5e34599fc8ba1e8889095bd56a71fd9802ed5a51 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:46 +0200 Subject: [PATCH 1813/2509] [S390] sclp_tty: Fix scheduling while atomic bug. Finally fixes a possible scheduling while in atomic context bug. The driver used to wait on a waitqueue if no empty buffer was available. This could lead to a deadlock if the driver was called from non-schedulable context. So fix this. The write operation may fail now. It returns the number of characters accepted. put_char will never fail, since it writes characters to an intermediate buffer which gets flushed as soon as it is full. That means the driver now can busy wait if something is in the intermediate buffer and a write_string operation follows. Seems to be an acceptable compromise, since that shouldn't happen too often. Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky --- drivers/s390/char/sclp_tty.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index bcf691af533..434ba04b130 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -48,8 +47,6 @@ static int sclp_tty_buffer_count; static struct sclp_buffer *sclp_ttybuf; /* Timer for delayed output of console messages. */ static struct timer_list sclp_tty_timer; -/* Waitqueue to wait for buffers to get empty. */ -static wait_queue_head_t sclp_tty_waitq; static struct tty_struct *sclp_tty; static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; @@ -128,7 +125,6 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) struct sclp_buffer, list); spin_unlock_irqrestore(&sclp_tty_lock, flags); } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); - wake_up(&sclp_tty_waitq); /* check if the tty needs a wake up call */ if (sclp_tty != NULL) { tty_wakeup(sclp_tty); @@ -176,27 +172,27 @@ sclp_tty_timeout(unsigned long data) /* * Write a string to the sclp tty. */ -static void -sclp_tty_write_string(const unsigned char *str, int count) +static int sclp_tty_write_string(const unsigned char *str, int count, int may_fail) { unsigned long flags; void *page; int written; + int overall_written; struct sclp_buffer *buf; if (count <= 0) - return; + return 0; + overall_written = 0; spin_lock_irqsave(&sclp_tty_lock, flags); do { /* Create a sclp output buffer if none exists yet */ if (sclp_ttybuf == NULL) { while (list_empty(&sclp_tty_pages)) { spin_unlock_irqrestore(&sclp_tty_lock, flags); - if (in_interrupt()) - sclp_sync_wait(); + if (may_fail) + goto out; else - wait_event(sclp_tty_waitq, - !list_empty(&sclp_tty_pages)); + sclp_sync_wait(); spin_lock_irqsave(&sclp_tty_lock, flags); } page = sclp_tty_pages.next; @@ -206,6 +202,7 @@ sclp_tty_write_string(const unsigned char *str, int count) } /* try to write the string to the current output buffer */ written = sclp_write(sclp_ttybuf, str, count); + overall_written += written; if (written == count) break; /* @@ -231,6 +228,8 @@ sclp_tty_write_string(const unsigned char *str, int count) add_timer(&sclp_tty_timer); } spin_unlock_irqrestore(&sclp_tty_lock, flags); +out: + return overall_written; } /* @@ -242,11 +241,10 @@ static int sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) { if (sclp_tty_chars_count > 0) { - sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); + sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); sclp_tty_chars_count = 0; } - sclp_tty_write_string(buf, count); - return count; + return sclp_tty_write_string(buf, count, 1); } /* @@ -264,9 +262,10 @@ sclp_tty_put_char(struct tty_struct *tty, unsigned char ch) { sclp_tty_chars[sclp_tty_chars_count++] = ch; if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) { - sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); + sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); sclp_tty_chars_count = 0; - } return 1; + } + return 1; } /* @@ -277,7 +276,7 @@ static void sclp_tty_flush_chars(struct tty_struct *tty) { if (sclp_tty_chars_count > 0) { - sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); + sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); sclp_tty_chars_count = 0; } } @@ -316,7 +315,7 @@ static void sclp_tty_flush_buffer(struct tty_struct *tty) { if (sclp_tty_chars_count > 0) { - sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); + sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); sclp_tty_chars_count = 0; } } @@ -577,7 +576,6 @@ sclp_tty_init(void) } INIT_LIST_HEAD(&sclp_tty_outqueue); spin_lock_init(&sclp_tty_lock); - init_waitqueue_head(&sclp_tty_waitq); init_timer(&sclp_tty_timer); sclp_ttybuf = NULL; sclp_tty_buffer_count = 0; -- GitLab From 992860e991f2015fb8c8df65aa32afa0dcbb4430 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 14 Jul 2008 10:28:38 +0200 Subject: [PATCH 1814/2509] lockdep: fix ftrace irq tracing false positive fix this false positive: [ 0.020000] ------------[ cut here ]------------ [ 0.020000] WARNING: at kernel/lockdep.c:2718 check_flags+0x14a/0x170() [ 0.020000] Modules linked in: [ 0.020000] Pid: 0, comm: swapper Not tainted 2.6.26-tip-00343-gd7e5521-dirty #14486 [ 0.020000] [] warn_on_slowpath+0x54/0x80 [ 0.020000] [] ? _spin_unlock_irqrestore+0x61/0x70 [ 0.020000] [] ? release_console_sem+0x201/0x210 [ 0.020000] [] ? __kernel_text_address+0x35/0x40 [ 0.020000] [] ? dump_trace+0x5e/0x140 [ 0.020000] [] ? __lock_acquire+0x245/0x820 [ 0.020000] [] check_flags+0x14a/0x170 [ 0.020000] [] ? lock_acquire+0x48/0xc0 [ 0.020000] [] lock_acquire+0x51/0xc0 [ 0.020000] [] ? down+0x2c/0x40 [ 0.020000] [] ? sched_clock+0x9/0x10 [ 0.020000] [] _write_lock+0x32/0x60 [ 0.020000] [] ? request_resource+0x1f/0xb0 [ 0.020000] [] request_resource+0x1f/0xb0 [ 0.020000] [] vgacon_startup+0x2bd/0x3e0 [ 0.020000] [] con_init+0x19/0x22f [ 0.020000] [] ? tty_register_ldisc+0x5c/0x70 [ 0.020000] [] console_init+0x20/0x2e [ 0.020000] [] start_kernel+0x20c/0x379 [ 0.020000] [] ? unknown_bootoption+0x0/0x1f6 [ 0.020000] [] __init_begin+0x99/0xa1 [ 0.020000] ======================= [ 0.020000] ---[ end trace 4eaa2a86a8e2da22 ]--- [ 0.020000] possible reason: unannotated irqs-on. [ 0.020000] irq event stamp: 0 which occurs if CONFIG_TRACE_IRQFLAGS=y, CONFIG_DEBUG_LOCKDEP=y, but CONFIG_PROVE_LOCKING is disabled. Signed-off-by: Ingo Molnar --- kernel/lockdep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 7553a28b99c..fc5d5aabd77 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -2688,7 +2688,8 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) */ static void check_flags(unsigned long flags) { -#if defined(CONFIG_DEBUG_LOCKDEP) && defined(CONFIG_TRACE_IRQFLAGS) +#if defined(CONFIG_PROVE_LOCKING) && defined(CONFIG_DEBUG_LOCKDEP) && \ + defined(CONFIG_TRACE_IRQFLAGS) if (!debug_locks) return; -- GitLab From d12c1a37925a8ec386994169605fe99217295199 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 14 Jul 2008 12:09:28 +0200 Subject: [PATCH 1815/2509] lockdep: fix kernel/fork.c warning fix: [ 0.184011] ------------[ cut here ]------------ [ 0.188011] WARNING: at kernel/fork.c:918 copy_process+0x1c0/0x1084() [ 0.192011] Pid: 0, comm: swapper Not tainted 2.6.26-tip-00351-g01d4a50-dirty #14521 [ 0.196011] [] warn_on_slowpath+0x3c/0x60 [ 0.200012] [] ? __alloc_pages_internal+0x92/0x36b [ 0.208012] [] ? __spin_lock_init+0x24/0x4a [ 0.212012] [] copy_process+0x1c0/0x1084 [ 0.216013] [] do_fork+0xb8/0x1ad [ 0.220013] [] ? acpi_os_release_lock+0x8/0xa [ 0.228013] [] ? acpi_os_vprintf+0x20/0x24 [ 0.232014] [] kernel_thread+0x75/0x7d [ 0.236014] [] ? kernel_init+0x0/0x24a [ 0.240014] [] ? kernel_init+0x0/0x24a [ 0.244014] [] ? kernel_thread_helper+0x0/0x10 [ 0.252015] [] rest_init+0x14/0x50 [ 0.256015] [] start_kernel+0x2b9/0x2c0 [ 0.260015] [] __init_begin+0x4f/0x57 [ 0.264016] ======================= [ 0.268016] ---[ end trace 4eaa2a86a8e2da22 ]--- [ 0.272016] enabled ExtINT on CPU#0 which occurs if CONFIG_TRACE_IRQFLAGS=y, CONFIG_DEBUG_LOCKDEP=y, but CONFIG_PROVE_LOCKING is disabled. Signed-off-by: Ingo Molnar --- kernel/fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fork.c b/kernel/fork.c index 19908b26cf8..cdb1f82d3bd 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 +#ifdef CONFIG_PROVE_LOCKING DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); #endif -- GitLab From d2886ea368a67704ecc13e69075f18a9d74cb12b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 May 2008 00:34:07 +0200 Subject: [PATCH 1816/2509] scsi: sd: optionally set power condition in START STOP UNIT Adds a new scsi_device flag, start_stop_pwr_cond: If enabled, the sd driver will not send plain START STOP UNIT commands but ones with the power condition field set to 3 (standby) or 1 (active) respectively. Some FireWire disk firmwares do not stop the motor if power condition is zero. Or worse, they become unresponsive after a START STOP UNIT with power condition = 0 and start = 0. http://lkml.org/lkml/2008/4/29/704 This patch only adds the necessary code to sd_mod but doesn't activate it. Follow-up patches to the FireWire drivers will add detection of affected devices and enable the code for them. I did not add power condition values to scsi_error.c::scsi_eh_try_stu() for now. The three firmwares which suffer from above mentioned problems do not need START STOP UNIT in the error handler, and they are not adversely affected by START STOP UNIT with power condition = 0 and start = 1 (like scsi_eh_try_stu() sends it if scsi_device.allow_restart is enabled). Signed-off-by: Stefan Richter Tested-by: Tino Keitel --- drivers/scsi/sd.c | 5 +++++ include/scsi/scsi_device.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 01cefbb2d53..d53312c4254 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1124,6 +1124,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) cmd[1] = 1; /* Return immediately */ memset((void *) &cmd[2], 0, 8); cmd[4] = 1; /* Start spin cycle */ + if (sdkp->device->start_stop_pwr_cond) + cmd[4] |= 1 << 4; scsi_execute_req(sdkp->device, cmd, DMA_NONE, NULL, 0, &sshdr, SD_TIMEOUT, SD_MAX_RETRIES); @@ -1790,6 +1792,9 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) if (start) cmd[4] |= 1; /* START */ + if (sdp->start_stop_pwr_cond) + cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */ + if (!scsi_device_online(sdp)) return -ENODEV; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index f6a9fe0ef09..00b78763a1b 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -134,6 +134,7 @@ struct scsi_device { unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ + unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned select_no_atn:1; unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ -- GitLab From ffcaade3109c3a4c0a2c601cf2a44d55b4c3af37 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 May 2008 00:35:04 +0200 Subject: [PATCH 1817/2509] firewire: fw-sbp2: fix spindown for PL-3507 and TSB42AA9 firmwares Reported by Tino Keitel: PL-3507 with firmware from Prolific does not spin down the disk on START STOP UNIT with power condition = 0 and start = 0. It does however work with power condition = 2 or 3. Also found while investigating this: DViCO Momobay CX-1 and FX-3A (TI TSB42AA9/A based) become unresponsive after START STOP UNIT with power condition = 0 and start = 0. They stay responsive if power condition is set when stopping the motor. Signed-off-by: Stefan Richter Tested-by: Tino Keitel --- drivers/firewire/fw-sbp2.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 227d2e036cd..bb8830fb0b7 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -86,6 +86,11 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * - delay inquiry * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. * + * - power condition + * Set the power condition field in the START STOP UNIT commands sent by + * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). + * Some disks need this to spin down or to resume properly. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -97,6 +102,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 #define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 #define SBP2_INQUIRY_DELAY 12 +#define SBP2_WORKAROUND_POWER_CONDITION 0x20 #define SBP2_WORKAROUND_OVERRIDE 0x100 static int sbp2_param_workarounds; @@ -107,6 +113,8 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) + ", set power condition in start stop unit = " + __stringify(SBP2_WORKAROUND_POWER_CONDITION) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -310,18 +318,25 @@ static const struct { .firmware_revision = 0x002800, .model = 0x001010, .workarounds = SBP2_WORKAROUND_INQUIRY_36 | - SBP2_WORKAROUND_MODE_SENSE_8, + SBP2_WORKAROUND_MODE_SENSE_8 | + SBP2_WORKAROUND_POWER_CONDITION, }, /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { .firmware_revision = 0x002800, .model = 0x000000, - .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY | + SBP2_WORKAROUND_POWER_CONDITION, }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model = ~0, .workarounds = SBP2_WORKAROUND_INQUIRY_36, }, + /* PL-3507 bridge with Prolific firmware */ { + .firmware_revision = 0x012800, + .model = ~0, + .workarounds = SBP2_WORKAROUND_POWER_CONDITION, + }, /* Symbios bridge */ { .firmware_revision = 0xa0b800, .model = ~0, @@ -1540,6 +1555,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) sdev->fix_capacity = 1; + if (lu->tgt->workarounds & SBP2_WORKAROUND_POWER_CONDITION) + sdev->start_stop_pwr_cond = 1; + if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); -- GitLab From 3719122a520af2957031859317e74858ab4d3f4b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 May 2008 00:35:55 +0200 Subject: [PATCH 1818/2509] ieee1394: sbp2: fix spindown for PL-3507 and TSB42AA9 firmwares Reported by Tino Keitel: PL-3507 with firmware from Prolific does not spin down the disk on START STOP UNIT with power condition = 0 and start = 0. It does however work with power condition = 2 or 3. Also found while investigating this: DViCO Momobay CX-1 and FX-3A (TI TSB42AA9/A based) become unresponsive after START STOP UNIT with power condition = 0 and start = 0. They stay responsive if power condition is set when stopping the motor. Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 20 ++++++++++++++++++-- drivers/ieee1394/sbp2.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index a5ceff287a2..219164da281 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -186,6 +186,11 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * - delay inquiry * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. * + * - power condition + * Set the power condition field in the START STOP UNIT commands sent by + * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). + * Some disks need this to spin down or to resume properly. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -199,6 +204,8 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) + ", set power condition in start stop unit = " + __stringify(SBP2_WORKAROUND_POWER_CONDITION) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -359,18 +366,25 @@ static const struct { .firmware_revision = 0x002800, .model_id = 0x001010, .workarounds = SBP2_WORKAROUND_INQUIRY_36 | - SBP2_WORKAROUND_MODE_SENSE_8, + SBP2_WORKAROUND_MODE_SENSE_8 | + SBP2_WORKAROUND_POWER_CONDITION, }, /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { .firmware_revision = 0x002800, .model_id = 0x000000, - .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY | + SBP2_WORKAROUND_POWER_CONDITION, }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model_id = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_INQUIRY_36, }, + /* PL-3507 bridge with Prolific firmware */ { + .firmware_revision = 0x012800, + .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_POWER_CONDITION, + }, /* Symbios bridge */ { .firmware_revision = 0xa0b800, .model_id = SBP2_ROM_VALUE_WILDCARD, @@ -2002,6 +2016,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) sdev->skip_ms_page_8 = 1; if (lu->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) sdev->fix_capacity = 1; + if (lu->workarounds & SBP2_WORKAROUND_POWER_CONDITION) + sdev->start_stop_pwr_cond = 1; if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); return 0; diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 80d8e097b06..875428bc8d2 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -345,6 +345,7 @@ enum sbp2lu_state_types { #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 #define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 #define SBP2_INQUIRY_DELAY 12 +#define SBP2_WORKAROUND_POWER_CONDITION 0x20 #define SBP2_WORKAROUND_OVERRIDE 0x100 #endif /* SBP2_H */ -- GitLab From 2635f96f9086409de0ec882a210f374c012bffc3 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 May 2008 00:36:47 +0200 Subject: [PATCH 1819/2509] firewire: fw-sbp2: spin disks down on suspend and shutdown This instructs sd_mod to send START STOP UNIT on suspend and resume, and on driver unbinding or unloading (including when the system is shut down). We don't do this though if multiple initiators may log in to the target. Signed-off-by: Stefan Richter Tested-by: Tino Keitel --- drivers/firewire/fw-sbp2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index bb8830fb0b7..53fc5a641e6 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1545,6 +1545,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) sdev->use_10_for_rw = 1; + if (sbp2_param_exclusive_login) + sdev->manage_start_stop = 1; + if (sdev->type == TYPE_ROM) sdev->use_10_for_ms = 1; -- GitLab From 82f06e86117680ada35fdb76c8852268d994cd99 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 May 2008 00:37:14 +0200 Subject: [PATCH 1820/2509] ieee1394: sbp2: spin disks down on suspend and shutdown This instructs sd_mod to send START STOP UNIT on suspend and resume, and on driver unbinding or unloading (including when the system is shut down). We don't do this though if multiple initiators may log in to the target. Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 219164da281..9cbf3154d24 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -2009,6 +2009,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) sdev->use_10_for_rw = 1; + if (sbp2_exclusive_login) + sdev->manage_start_stop = 1; if (sdev->type == TYPE_ROM) sdev->use_10_for_ms = 1; if (sdev->type == TYPE_DISK && -- GitLab From fde675fa2a1b07108976b42b20c9e69c80a53248 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 2 May 2008 20:14:52 +0200 Subject: [PATCH 1821/2509] ieee1394: reduce log noise about config ROM CRC errors This avoids redundant messages about a special and usually harmless firmware flaw. Signed-off-by: Stefan Richter --- drivers/ieee1394/csr1212.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c index e8122def164..9f95337139e 100644 --- a/drivers/ieee1394/csr1212.c +++ b/drivers/ieee1394/csr1212.c @@ -1049,6 +1049,24 @@ int csr1212_read(struct csr1212_csr *csr, u32 offset, void *buffer, u32 len) return -ENOENT; } +/* + * Apparently there are many different wrong implementations of the CRC + * algorithm. We don't fail, we just warn... approximately once per GUID. + */ +static void +csr1212_check_crc(const u32 *buffer, size_t length, u16 crc, __be32 *guid) +{ + static u64 last_bad_eui64; + u64 eui64 = ((u64)be32_to_cpu(guid[0]) << 32) | be32_to_cpu(guid[1]); + + if (csr1212_crc16(buffer, length) == crc || + csr1212_msft_crc16(buffer, length) == crc || + eui64 == last_bad_eui64) + return; + + printk(KERN_DEBUG "ieee1394: config ROM CRC error\n"); + last_bad_eui64 = eui64; +} /* Parse a chunk of data as a Config ROM */ @@ -1092,11 +1110,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr) return ret; } - /* Apparently there are many different wrong implementations of the CRC - * algorithm. We don't fail, we just warn. */ - if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) && - (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc)) - printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n"); + csr1212_check_crc(bi->data, bi->crc_length, bi->crc, + &csr->bus_info_data[3]); cr = CSR1212_MALLOC(sizeof(*cr)); if (!cr) @@ -1205,11 +1220,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv, &cache->data[bytes_to_quads(kv->offset - cache->offset)]; kvi_len = be16_to_cpu(kvi->length); - /* Apparently there are many different wrong implementations of the CRC - * algorithm. We don't fail, we just warn. */ - if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) && - (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) - printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n"); + /* GUID is wrong in here in case of extended ROM. We don't care. */ + csr1212_check_crc(kvi->data, kvi_len, kvi->crc, &cache->data[3]); switch (kv->key.type) { case CSR1212_KV_TYPE_DIRECTORY: -- GitLab From 055a7da0bb7b14f2f5009bf1c486a6e965e1e7ac Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 19 May 2008 22:07:28 +0200 Subject: [PATCH 1822/2509] ieee1394: video1394: reorder module init, prepare BKL removal This prepares video1394 for removal of the BKL (big kernel lock): It allows video1394_open() to be called while video1394_init_module() is still in progress. Signed-off-by: Stefan Richter --- drivers/ieee1394/highlevel.c | 4 +--- drivers/ieee1394/highlevel.h | 13 ++++++++++++- drivers/ieee1394/video1394.c | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c index fa2bfec0fca..918ffc4fc8a 100644 --- a/drivers/ieee1394/highlevel.c +++ b/drivers/ieee1394/highlevel.c @@ -228,10 +228,8 @@ void hpsb_register_highlevel(struct hpsb_highlevel *hl) { unsigned long flags; + hpsb_init_highlevel(hl); INIT_LIST_HEAD(&hl->addr_list); - INIT_LIST_HEAD(&hl->host_info_list); - - rwlock_init(&hl->host_info_lock); down_write(&hl_drivers_sem); list_add_tail(&hl->hl_list, &hl_drivers); diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h index eb9fe321e09..bc5d0854c17 100644 --- a/drivers/ieee1394/highlevel.h +++ b/drivers/ieee1394/highlevel.h @@ -2,7 +2,7 @@ #define IEEE1394_HIGHLEVEL_H #include -#include +#include #include struct module; @@ -103,6 +103,17 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length); +/** + * hpsb_init_highlevel - initialize a struct hpsb_highlevel + * + * This is only necessary if hpsb_get_hostinfo_bykey can be called + * before hpsb_register_highlevel. + */ +static inline void hpsb_init_highlevel(struct hpsb_highlevel *hl) +{ + rwlock_init(&hl->host_info_lock); + INIT_LIST_HEAD(&hl->host_info_list); +} void hpsb_register_highlevel(struct hpsb_highlevel *hl); void hpsb_unregister_highlevel(struct hpsb_highlevel *hl); diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index e24772d336e..069b9f6bf16 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1503,6 +1503,8 @@ static int __init video1394_init_module (void) { int ret; + hpsb_init_highlevel(&video1394_highlevel); + cdev_init(&video1394_cdev, &video1394_fops); video1394_cdev.owner = THIS_MODULE; ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16); -- GitLab From 3aea50a379ed152bcb86b24b65a4cb59be82446f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 May 2008 11:57:41 +0100 Subject: [PATCH 1823/2509] ieee1394: raw1394: Push the BKL down into the driver ioctls Actually in this case wrap the function for now. Signed-off-by: Alan Cox Added raw1394_compat_ioctl hunk. Signed-off-by: Stefan Richter --- drivers/ieee1394/raw1394.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index ec2a0adbedb..96f2847b040 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2549,8 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) } /* ioctl is only used for rawiso operations */ -static int raw1394_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long do_raw1394_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct file_info *fi = file->private_data; void __user *argp = (void __user *)arg; @@ -2656,6 +2656,16 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +static long raw1394_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret; + lock_kernel(); + ret = do_raw1394_ioctl(file, cmd, arg); + unlock_kernel(); + return ret; +} + #ifdef CONFIG_COMPAT struct raw1394_iso_packets32 { __u32 n_packets; @@ -2690,7 +2700,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { infos = compat_ptr(infos32); if (!copy_to_user(&dst->infos, &infos, sizeof infos)) - err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst); + err = do_raw1394_ioctl(file, cmd, (unsigned long)dst); } return err; } @@ -2731,7 +2741,7 @@ static long raw1394_compat_ioctl(struct file *file, case RAW1394_IOC_ISO_GET_STATUS: case RAW1394_IOC_ISO_SHUTDOWN: case RAW1394_IOC_ISO_QUEUE_ACTIVITY: - err = raw1394_ioctl(NULL, file, cmd, arg); + err = do_raw1394_ioctl(file, cmd, arg); break; /* These request have different format. */ case RAW1394_IOC_ISO_RECV_PACKETS32: @@ -2984,7 +2994,7 @@ static const struct file_operations raw1394_fops = { .read = raw1394_read, .write = raw1394_write, .mmap = raw1394_mmap, - .ioctl = raw1394_ioctl, + .unlocked_ioctl = raw1394_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = raw1394_compat_ioctl, #endif -- GitLab From 435f972697fcd4c424db941f0ea8f2e38eda2b39 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Thu, 3 Jul 2008 18:52:28 +0200 Subject: [PATCH 1824/2509] ieee1394: dump mmapped iso buffers in core files Currently, core files do not contain the mmapped memory of the video1394 or dv1394 devices, which contain the actual video input, making it impossible to analyse the cause of abnormal program termination for image analysis or (de)compression software. Fix that. Signed-off-by: Philippe De Muyter Also affects users of the rawiso ioctl API of raw1394. Signed-off-by: Stefan Richter --- drivers/ieee1394/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c index 73685e7dc7e..1aba8c13fe8 100644 --- a/drivers/ieee1394/dma.c +++ b/drivers/ieee1394/dma.c @@ -274,7 +274,7 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, vma->vm_ops = &dma_region_vm_ops; vma->vm_private_data = dma; vma->vm_file = file; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_RESERVED | VM_ALWAYSDUMP; return 0; } -- GitLab From e534fe16b987780744da351acece2a4699783096 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 24 May 2008 16:41:09 +0200 Subject: [PATCH 1825/2509] firewire: implement broadcast_channel CSR for 1394a compliance See IEEE 1394a clause 8.3.2.3.11. Signed-off-by: Stefan Richter --- drivers/firewire/fw-card.c | 1 + drivers/firewire/fw-transaction.c | 20 +++++++++++++++++--- drivers/firewire/fw-transaction.h | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 5b4c0d9f517..96340ce690d 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -403,6 +403,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, card->current_tlabel = 0; card->tlabel_mask = 0; card->color = 0; + card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; INIT_LIST_HEAD(&card->transaction_list); spin_lock_init(&card->lock); diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 03ae8a77c47..2f11ed1acf0 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request, int reg = offset & ~CSR_REGISTER_BASE; unsigned long long bus_time; __be32 *data = payload; + int rcode = RCODE_COMPLETE; switch (reg) { case CSR_CYCLE_TIME: case CSR_BUS_TIME: if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { - fw_send_response(card, request, RCODE_TYPE_ERROR); + rcode = RCODE_TYPE_ERROR; break; } @@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request, *data = cpu_to_be32(bus_time); else *data = cpu_to_be32(bus_time >> 25); - fw_send_response(card, request, RCODE_COMPLETE); + break; + + case CSR_BROADCAST_CHANNEL: + if (tcode == TCODE_READ_QUADLET_REQUEST) + *data = cpu_to_be32(card->broadcast_channel); + else if (tcode == TCODE_WRITE_QUADLET_REQUEST) + card->broadcast_channel = + (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) | + BROADCAST_CHANNEL_INITIAL; + else + rcode = RCODE_TYPE_ERROR; break; case CSR_BUS_MANAGER_ID: @@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request, case CSR_BUSY_TIMEOUT: /* FIXME: Implement this. */ + default: - fw_send_response(card, request, RCODE_ADDRESS_ERROR); + rcode = RCODE_ADDRESS_ERROR; break; } + + fw_send_response(card, request, rcode); } static struct fw_address_handler registers = { diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 04d3854f656..f3a493d596c 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -80,6 +80,9 @@ #define CSR_SPEED_MAP 0x2000 #define CSR_SPEED_MAP_END 0x3000 +#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) +#define BROADCAST_CHANNEL_VALID (1 << 30) + #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) @@ -236,6 +239,7 @@ struct fw_card { */ int self_id_count; u32 topology_map[252 + 3]; + u32 broadcast_channel; spinlock_t lock; /* Take this lock when handling the lists in * this struct. */ -- GitLab From bbf094cf3dbd9a969dd17cf52325e9fab8dfbe91 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 24 May 2008 16:46:10 +0200 Subject: [PATCH 1826/2509] firewire: remove unused struct members Signed-off-by: Stefan Richter --- drivers/firewire/fw-card.c | 1 - drivers/firewire/fw-device.h | 1 - drivers/firewire/fw-ohci.c | 1 - drivers/firewire/fw-transaction.h | 2 -- 4 files changed, 5 deletions(-) diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 96340ce690d..1332b66ae0b 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -497,7 +497,6 @@ dummy_enable_phys_dma(struct fw_card *card, } static struct fw_card_driver dummy_driver = { - .name = "dummy", .enable = dummy_enable, .update_phy_reg = dummy_update_phy_reg, .set_config_rom = dummy_set_config_rom, diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 5f131f5129d..42305bbac72 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -62,7 +62,6 @@ struct fw_device { bool cmc; struct fw_card *card; struct device device; - struct list_head link; struct list_head client_list; u32 *config_rom; size_t config_rom_length; diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 0b66306af47..333b12544dd 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -2292,7 +2292,6 @@ ohci_queue_iso(struct fw_iso_context *base, } static const struct fw_card_driver ohci_driver = { - .name = ohci_driver_name, .enable = ohci_enable, .update_phy_reg = ohci_update_phy_reg, .set_config_rom = ohci_set_config_rom, diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index f3a493d596c..7e928e86022 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -352,8 +352,6 @@ int fw_iso_context_stop(struct fw_iso_context *ctx); struct fw_card_driver { - const char *name; - /* * Enable the given card with the given initial config rom. * This function is expected to activate the card, and either -- GitLab From 2147ef204f57191e0fff6d5d3d1a0336afa6cfae Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 24 May 2008 16:48:05 +0200 Subject: [PATCH 1827/2509] firewire: clean up some includes Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 7e928e86022..219094e3854 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -20,12 +20,12 @@ #define __fw_transaction_h #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) -- GitLab From 459f79235d8faa0050180c7e0c7bb4b2b52cbdfd Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 24 May 2008 16:50:22 +0200 Subject: [PATCH 1828/2509] firewire: clean up fw_card reference counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a functionally equivalent replacement of the current reference counting of struct fw_card instances. It only converts it to common idioms as suggested by Kristian Høgsberg: - struct kref replaces atomic_t as the counter. - wait_for_completion is used to wait for all card users to complete. BTW, it may make sense to count card->flush_timer and card->work as card users too. Signed-off-by: Stefan Richter --- drivers/firewire/fw-card.c | 30 ++++++++++++++++++++---------- drivers/firewire/fw-device.c | 5 ++--- drivers/firewire/fw-transaction.h | 20 ++++++++++++++++++-- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 1332b66ae0b..da873d795aa 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -16,12 +16,15 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include +#include #include #include +#include +#include +#include #include -#include + #include "fw-transaction.h" #include "fw-topology.h" #include "fw-device.h" @@ -396,7 +399,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, { static atomic_t index = ATOMIC_INIT(-1); - atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->driver = driver; card->device = device; @@ -405,6 +407,8 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, card->color = 0; card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; + kref_init(&card->kref); + init_completion(&card->done); INIT_LIST_HEAD(&card->transaction_list); spin_lock_init(&card->lock); setup_timer(&card->flush_timer, @@ -506,6 +510,14 @@ static struct fw_card_driver dummy_driver = { .enable_phys_dma = dummy_enable_phys_dma, }; +void +fw_card_release(struct kref *kref) +{ + struct fw_card *card = container_of(kref, struct fw_card, kref); + + complete(&card->done); +} + void fw_core_remove_card(struct fw_card *card) { @@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; fw_destroy_nodes(card); - /* - * Wait for all device workqueue jobs to finish. Otherwise the - * firewire-core module could be unloaded before the jobs ran. - */ - while (atomic_read(&card->device_count) > 0) - msleep(100); + + /* Wait for all users, especially device workqueue jobs, to finish. */ + fw_card_put(card); + wait_for_completion(&card->done); cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index d9c8daf7ae7..0855fb5568e 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -168,7 +168,7 @@ static void fw_device_release(struct device *dev) fw_node_put(device->node); kfree(device->config_rom); kfree(device); - atomic_dec(&card->device_count); + fw_card_put(card); } int fw_device_enable_phys_dma(struct fw_device *device) @@ -946,8 +946,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); - atomic_inc(&card->device_count); - device->card = card; + device->card = fw_card_get(card); device->node = fw_node_get(node); device->node_id = node->node_id; device->generation = card->generation; diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 219094e3854..2ae1b0d6cb7 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -19,14 +19,15 @@ #ifndef __fw_transaction_h #define __fw_transaction_h +#include #include #include #include +#include #include #include #include #include -#include #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) @@ -219,7 +220,8 @@ extern struct bus_type fw_bus_type; struct fw_card { const struct fw_card_driver *driver; struct device *device; - atomic_t device_count; + struct kref kref; + struct completion done; int node_id; int generation; @@ -260,6 +262,20 @@ struct fw_card { int bm_generation; }; +static inline struct fw_card *fw_card_get(struct fw_card *card) +{ + kref_get(&card->kref); + + return card; +} + +void fw_card_release(struct kref *kref); + +static inline void fw_card_put(struct fw_card *card) +{ + kref_put(&card->kref, fw_card_release); +} + /* * The iso packet format allows for an immediate header/payload part * stored in 'header' immediately after the packet info plus an -- GitLab From a7ea67823af4a7e442e92064b0fab46603a588f6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 25 May 2008 11:06:55 +0200 Subject: [PATCH 1829/2509] firewire: don't respond to broadcast write requests Contrary to a comment in the source, request->ack of a broadcast write request can be ACK_PENDING. Hence the existing check is insufficient. Debug dmesg before: AR spd 0 tl 00, ffc0 -> ffff, ack_pending , QW req, fffff0000234 = ffffffff AT spd 0 tl 00, ffff -> ffc0, ack_complete, W resp And the requesting node (linux1394) reports an unsolicited response. Debug dmesg after: AR spd 0 tl 00, ffc0 -> ffff, ack_pending , QW req, fffff0000234 = ffffffff Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 2f11ed1acf0..40db8075227 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -55,6 +55,9 @@ #define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff) #define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff) +#define HEADER_DESTINATION_IS_BROADCAST(q) \ + (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f)) + #define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22)) #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) #define PHY_IDENTIFIER(id) ((id) << 30) @@ -624,12 +627,9 @@ allocate_request(struct fw_packet *p) void fw_send_response(struct fw_card *card, struct fw_request *request, int rcode) { - /* - * Broadcast packets are reported as ACK_COMPLETE, so this - * check is sufficient to ensure we don't send response to - * broadcast packets or posted writes. - */ - if (request->ack != ACK_PENDING) { + /* unified transaction or broadcast transaction: don't respond */ + if (request->ack != ACK_PENDING || + HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { kfree(request); return; } -- GitLab From 0fe9b1ea60bc209c8c87afcbb1c2ec0b28835aa4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 30 Jun 2008 23:24:14 -0500 Subject: [PATCH 1830/2509] powerpc/85xx: Fix KSI8560 .dts Rename MPIC label to mpic to match all other 85xx .dts and to fix compile issue introduced by addition of the DMA node. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/ksi8560.dts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts index fd580439841..49737589ffc 100644 --- a/arch/powerpc/boot/dts/ksi8560.dts +++ b/arch/powerpc/boot/dts/ksi8560.dts @@ -59,7 +59,7 @@ memory-controller@2000 { compatible = "fsl,8540-memory-controller"; reg = <0x2000 0x1000>; - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; interrupts = <0x12 0x2>; }; @@ -68,7 +68,7 @@ reg = <0x20000 0x1000>; cache-line-size = <0x20>; /* 32 bytes */ cache-size = <0x40000>; /* L2, 256K */ - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; interrupts = <0x10 0x2>; }; @@ -79,7 +79,7 @@ compatible = "fsl-i2c"; reg = <0x3000 0x100>; interrupts = <0x2b 0x2>; - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; dfsrr; }; @@ -131,13 +131,13 @@ reg = <0x24520 0x20>; PHY1: ethernet-phy@1 { - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; reg = <0x1>; device_type = "ethernet-phy"; }; PHY2: ethernet-phy@2 { - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; reg = <0x2>; device_type = "ethernet-phy"; }; @@ -151,7 +151,7 @@ /* Mac address filled in by bootwrapper */ local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; phy-handle = <&PHY1>; }; @@ -163,11 +163,11 @@ /* Mac address filled in by bootwrapper */ local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>; - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; phy-handle = <&PHY2>; }; - MPIC: pic@40000 { + mpic: pic@40000 { #address-cells = <0>; #interrupt-cells = <2>; interrupt-controller; @@ -206,7 +206,7 @@ #interrupt-cells = <2>; interrupt-controller; interrupts = <0x2e 0x2>; - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; reg = <0x90c00 0x80>; compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic"; }; @@ -244,7 +244,7 @@ fsl,mdc-pin = <25>; PHY0: ethernet-phy@0 { - interrupt-parent = <&MPIC>; + interrupt-parent = <&mpic>; reg = <0x0>; device_type = "ethernet-phy"; }; -- GitLab From 491a7a436cc90e97d666cfc025e141ca3186f86c Mon Sep 17 00:00:00 2001 From: Rune Torgersen Date: Tue, 20 May 2008 14:39:17 -0500 Subject: [PATCH 1831/2509] cpm_uart: Fix cpm uart corruption with PREEMPT_RT Fix CPM serial port corruption when running with CONFIG_PREEMPT_RT. Userland usage of console, and kernel printf's were stepping on each others toes. Also only take lock if not in an oops. Signed-off-by: Rune Torgersen Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart_core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) mode change 100644 => 100755 drivers/serial/cpm_uart/cpm_uart_core.c diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c old mode 100644 new mode 100755 index 43f58dc69fc..d389a76b4af --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -969,6 +969,14 @@ static void cpm_uart_console_write(struct console *co, const char *s, unsigned int i; cbd_t __iomem *bdp, *bdbase; unsigned char *cp; + unsigned long flags; + int nolock = oops_in_progress; + + if (unlikely(nolock)) { + local_irq_save(flags); + } else { + spin_lock_irqsave(&pinfo->port.lock, flags); + } /* Get the address of the host memory buffer. */ @@ -1030,6 +1038,12 @@ static void cpm_uart_console_write(struct console *co, const char *s, ; pinfo->tx_cur = bdp; + + if (unlikely(nolock)) { + local_irq_restore(flags); + } else { + spin_unlock_irqrestore(&pinfo->port.lock, flags); + } } -- GitLab From 6c1160991283a12537b136a71d10d271997fd64c Mon Sep 17 00:00:00 2001 From: Rune Torgersen Date: Tue, 20 May 2008 14:28:57 -0500 Subject: [PATCH 1832/2509] powerpc: Fix pq2fads irq handling with PREEMPT_RT Fix interrupt threading issue on pq2fads when running with CONFIG_PREEMPT_RT Signed-off-by: Rune Torgersen Signed-off-by: Kumar Gala --- arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index a8013816125..9876d7e072f 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -109,7 +109,7 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq, { get_irq_desc(virq)->status |= IRQ_LEVEL; set_irq_chip_data(virq, h->host_data); - set_irq_chip(virq, &pq2ads_pci_ic); + set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq); return 0; } -- GitLab From deabeabf0bb8e6ad0b5917859893ac5af46d9b04 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 1 Jul 2008 17:04:38 +0400 Subject: [PATCH 1833/2509] powerpc/86xx: mpc8610_hpcd: fix interrupt trigger type for ULi IDE i8259 PIC is disabled on MPC8610HPCD, and ULi IDE is configured to use PCI sideband interrupt that is specified in the device tree. Current HPCD's device tree specify that IDE interrupt is low to high sensitive, but in practice ULi IDE throws active-high interrupts (not active-low as all normal PCI devices). Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8610_hpcd.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts index 65a5f64b233..981941e5d7a 100644 --- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -363,7 +363,7 @@ 0xe000 0 0 4 &mpic 1 1 /* IDSEL 0x1f */ - 0xf800 0 0 1 &mpic 3 0 + 0xf800 0 0 1 &mpic 3 2 0xf800 0 0 2 &mpic 0 1 >; -- GitLab From a3083220c089c626a66b66af0eff4f9220d5b797 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Thu, 26 Jun 2008 15:15:43 +0200 Subject: [PATCH 1834/2509] powerpc/85xx: TQM8548: add missing support for RTC and LM75 It adds the missing RTC node to tqm8548.dts and enables support for I2C, DS1307 and LM75 in the default configuration. Signed-off-by: Wolfgang Grandegger Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/tqm8548.dts | 5 + arch/powerpc/configs/85xx/tqm8548_defconfig | 143 +++++++++++++++++++- 2 files changed, 142 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts index 13cd7280cb2..2563112cabd 100644 --- a/arch/powerpc/boot/dts/tqm8548.dts +++ b/arch/powerpc/boot/dts/tqm8548.dts @@ -83,6 +83,11 @@ interrupts = <43 2>; interrupt-parent = <&mpic>; dfsrr; + + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; }; i2c@3100 { diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig index 5d5b898767a..b3b770be3cc 100644 --- a/arch/powerpc/configs/85xx/tqm8548_defconfig +++ b/arch/powerpc/configs/85xx/tqm8548_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Tue Jun 3 14:39:30 2008 +# Linux kernel version: 2.6.26-rc5 +# Thu Jun 26 14:40:02 2008 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_PPC_85xx=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_E500=y +# CONFIG_PPC_E500MC is not set CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y CONFIG_FSL_EMB_PERFMON=y @@ -470,6 +471,7 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 # # CONFIG_MTD_UBI_DEBUG is not set CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set @@ -734,31 +736,111 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set # 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 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_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_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # CONFIG_SPI is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +CONFIG_SENSORS_LM75=y +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -834,7 +916,56 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# 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 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A 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 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_RTC_DRV_PPC is not set # CONFIG_DMADEVICES is not set # CONFIG_UIO is not set -- GitLab From 5e82eb333949e2f1652bf70d36dfaa875306ae11 Mon Sep 17 00:00:00 2001 From: Nye Liu Date: Fri, 27 Jun 2008 13:01:00 -0700 Subject: [PATCH 1835/2509] powerpc/CPM: Minor cosmetic changes to udbg_putc udbg_putc is a *function pointer* that is initialized during udbg_init_cpm. It might not be initialized properly when called from udbg_putc_cpm(), so (recursively) call udbg_putc_cpm() directly. Signed-off-by: Nye Liu Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/cpm_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 9b75d164bdf..e4b7296acb2 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -37,7 +37,7 @@ static void udbg_putc_cpm(char c) u8 __iomem *txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]); if (c == '\n') - udbg_putc('\r'); + udbg_putc_cpm('\r'); while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000) ; @@ -53,7 +53,6 @@ void __init udbg_init_cpm(void) setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO); #endif udbg_putc = udbg_putc_cpm; - udbg_putc('X'); } } #endif -- GitLab From a712b65cd015d9bd05bce01f57a42cd6c73c4aa0 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 2 Jul 2008 10:00:56 -0500 Subject: [PATCH 1836/2509] powerpc/85xx: minor fixes for MPC85xx DS board port These issues were reported by Stephen Rothwell for another 85xx board port and pointed out by Chen Gong as issues in the DS port. * mpic OF node reference counting was off * of_device_id struct should be marked as __initdata Signed-off-by: Kumar Gala --- arch/powerpc/platforms/85xx/mpc85xx_ds.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index b010dc9dec6..8b2d63d4264 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -58,14 +58,13 @@ void __init mpc85xx_ds_pic_init(void) { struct mpic *mpic; struct resource r; - struct device_node *np = NULL; + struct device_node *np; #ifdef CONFIG_PPC_I8259 struct device_node *cascade_node = NULL; int cascade_irq; #endif np = of_find_node_by_type(np, "open-pic"); - if (np == NULL) { printk(KERN_ERR "Could not find open-pic node\n"); return; @@ -82,6 +81,7 @@ void __init mpc85xx_ds_pic_init(void) MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); + of_node_put(np); mpic_init(mpic); @@ -185,7 +185,7 @@ static int __init mpc8544_ds_probe(void) } } -static struct of_device_id mpc85xxds_ids[] = { +static struct of_device_id __initdata mpc85xxds_ids[] = { { .type = "soc", }, { .compatible = "soc", }, {}, -- GitLab From 2f3804edf971d2080243d2b4552bfd61ddfbf969 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 2 Jul 2008 01:36:15 -0500 Subject: [PATCH 1837/2509] powerpc/85xx: Add support for MPC8536DS Add support for the MPC8536 process and MPC8536DS reference board. The MPC8536 is an e500v2 based SoC which eTSEC, USB, SATA, PCI, and PCIe. The USB and SATA IP blocks are similiar to those on the PQ2 Pro SoCs and thus use the same drivers. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8536ds.dts | 420 ++++++ arch/powerpc/configs/mpc8536_ds_defconfig | 1637 +++++++++++++++++++++ arch/powerpc/platforms/85xx/Kconfig | 6 + arch/powerpc/platforms/85xx/Makefile | 1 + arch/powerpc/platforms/85xx/mpc8536_ds.c | 125 ++ arch/powerpc/sysdev/fsl_pci.c | 2 + include/linux/pci_ids.h | 2 + 7 files changed, 2193 insertions(+) create mode 100644 arch/powerpc/boot/dts/mpc8536ds.dts create mode 100644 arch/powerpc/configs/mpc8536_ds_defconfig create mode 100644 arch/powerpc/platforms/85xx/mpc8536_ds.c diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts new file mode 100644 index 00000000000..98ad27a2dde --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -0,0 +1,420 @@ +/* + * MPC8536 DS Device Tree Source + * + * Copyright 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/dts-v1/; + +/ { + model = "fsl,mpc8536ds"; + compatible = "fsl,mpc8536ds"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + ethernet0 = &enet0; + ethernet1 = &enet1; + serial0 = &serial0; + serial1 = &serial1; + pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; + pci3 = &pci3; + }; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8536@0 { + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 00000000>; // Filled by U-Boot + }; + + soc@ffe00000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + ranges = <0x0 0xffe00000 0x100000>; + reg = <0xffe00000 0x1000>; + bus-frequency = <0>; // Filled out by uboot. + + memory-controller@2000 { + compatible = "fsl,mpc8536-memory-controller"; + reg = <0x2000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <18 0x2>; + }; + + L2: l2-cache-controller@20000 { + compatible = "fsl,mpc8536-l2-cache-controller"; + reg = <0x20000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <16 0x2>; + }; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <43 0x2>; + interrupt-parent = <&mpic>; + dfsrr; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <43 0x2>; + interrupt-parent = <&mpic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds3232"; + reg = <0x68>; + }; + }; + + dma@21300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8536-dma", "fsl,eloplus-dma"; + reg = <0x21300 4>; + ranges = <0 0x21100 0x200>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + cell-index = <0>; + interrupt-parent = <&mpic>; + interrupts = <14 0x2>; + }; + dma-channel@80 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + cell-index = <1>; + interrupt-parent = <&mpic>; + interrupts = <15 0x2>; + }; + dma-channel@100 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + cell-index = <2>; + interrupt-parent = <&mpic>; + interrupts = <16 0x2>; + }; + dma-channel@180 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + cell-index = <3>; + interrupt-parent = <&mpic>; + interrupts = <17 0x2>; + }; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + usb@22000 { + compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; + reg = <0x22000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <28 0x2>; + phy_type = "ulpi"; + }; + + usb@23000 { + compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; + reg = <0x23000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <46 0x2>; + phy_type = "ulpi"; + }; + + enet0: ethernet@24000 { + cell-index = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <0x24000 0x1000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <29 2 30 2 34 2>; + interrupt-parent = <&mpic>; + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + }; + + enet1: ethernet@26000 { + cell-index = <1>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <0x26000 0x1000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <31 2 32 2 33 2>; + interrupt-parent = <&mpic>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; + }; + + usb@2b000 { + compatible = "fsl,mpc8536-usb2-dr", "fsl-usb2-dr"; + reg = <0x2b000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <60 0x2>; + dr_mode = "peripheral"; + phy_type = "ulpi"; + }; + + serial0: serial@4500 { + cell-index = <0>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4500 0x100>; + clock-frequency = <0>; + interrupts = <42 0x2>; + interrupt-parent = <&mpic>; + }; + + serial1: serial@4600 { + cell-index = <1>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + clock-frequency = <0>; + interrupts = <42 0x2>; + interrupt-parent = <&mpic>; + }; + + sata@18000 { + compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; + reg = <0x18000 0x1000>; + cell-index = <1>; + interrupts = <74 0x2>; + interrupt-parent = <&mpic>; + }; + + sata@19000 { + compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; + reg = <0x19000 0x1000>; + cell-index = <2>; + interrupts = <41 0x2>; + interrupt-parent = <&mpic>; + }; + + global-utilities@e0000 { //global utilities block + compatible = "fsl,mpc8548-guts"; + reg = <0xe0000 0x1000>; + fsl,has-rstcr; + }; + + mpic: pic@40000 { + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <0x40000 0x40000>; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + + msi@41600 { + compatible = "fsl,mpc8536-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>; + }; + }; + + pci0: pci@ffe08000 { + cell-index = <0>; + compatible = "fsl,mpc8540-pci"; + device_type = "pci"; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + + /* IDSEL 0x11 J17 Slot 1 */ + 0x8800 0 0 1 &mpic 1 1 + 0x8800 0 0 2 &mpic 2 1 + 0x8800 0 0 3 &mpic 3 1 + 0x8800 0 0 4 &mpic 4 1>; + + interrupt-parent = <&mpic>; + interrupts = <24 0x2>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x80000000 0x80000000 0 0x10000000 + 0x01000000 0 0x00000000 0xffc00000 0 0x00010000>; + clock-frequency = <66666666>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe08000 0x1000>; + }; + + pci1: pcie@ffe09000 { + cell-index = <1>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe09000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x98000000 0x98000000 0 0x08000000 + 0x01000000 0 0x00000000 0xffc20000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <25 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 4 1 + 0000 0 0 2 &mpic 5 1 + 0000 0 0 3 &mpic 6 1 + 0000 0 0 4 &mpic 7 1 + >; + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0x98000000 + 0x02000000 0 0x98000000 + 0 0x08000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00010000>; + }; + }; + + pci2: pcie@ffe0a000 { + cell-index = <2>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe0a000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x90000000 0x90000000 0 0x08000000 + 0x01000000 0 0x00000000 0xffc10000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <26 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 0 1 + 0000 0 0 2 &mpic 1 1 + 0000 0 0 3 &mpic 2 1 + 0000 0 0 4 &mpic 3 1 + >; + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0x90000000 + 0x02000000 0 0x90000000 + 0 0x08000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00010000>; + }; + }; + + pci3: pcie@ffe0b000 { + cell-index = <3>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe0b000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000 + 0x01000000 0 0x00000000 0xffc30000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <27 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 8 1 + 0000 0 0 2 &mpic 9 1 + 0000 0 0 3 &mpic 10 1 + 0000 0 0 4 &mpic 11 1 + >; + + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0xa0000000 + 0x02000000 0 0xa0000000 + 0 0x20000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00100000>; + }; + }; +}; diff --git a/arch/powerpc/configs/mpc8536_ds_defconfig b/arch/powerpc/configs/mpc8536_ds_defconfig new file mode 100644 index 00000000000..f1e2931de5d --- /dev/null +++ b/arch/powerpc/configs/mpc8536_ds_defconfig @@ -0,0 +1,1637 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc8 +# Wed Jul 2 01:34:26 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +CONFIG_PPC_85xx=y +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_E500=y +# CONFIG_PPC_E500MC is not set +CONFIG_BOOKE=y +CONFIG_FSL_BOOKE=y +CONFIG_FSL_EMB_PERFMON=y +# CONFIG_PHYS_64BIT is not set +CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +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 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFAULT_UIMAGE=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +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=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL 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 is not set +# 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=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +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 +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_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# 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=y +# 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 + +# +# Platform support +# +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_MPC85xx=y +# CONFIG_MPC8540_ADS is not set +# CONFIG_MPC8560_ADS is not set +# CONFIG_MPC85xx_CDS is not set +# CONFIG_MPC85xx_MDS is not set +CONFIG_MPC8536_DS=y +# CONFIG_MPC85xx_DS is not set +# CONFIG_KSI8560 is not set +# CONFIG_STX_GP3 is not set +# CONFIG_TQM8540 is not set +# CONFIG_TQM8541 is not set +# CONFIG_TQM8548 is not set +# CONFIG_TQM8555 is not set +# CONFIG_TQM8560 is not set +# CONFIG_SBC8548 is not set +# CONFIG_SBC8560 is not set +# CONFIG_IPIC is not set +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +CONFIG_HIGHMEM=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=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_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_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_FSL_SOC=y +CONFIG_FSL_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_PHYSICAL_ALIGN=0x10000000 +CONFIG_TASK_SIZE=0xc0000000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +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_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE=y +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +# 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=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_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +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 +# 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 +CONFIG_FIB_RULES=y + +# +# 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_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=y +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=524288 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_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=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y +# 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=y +# 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_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +# CONFIG_SATA_AHCI is not set +CONFIG_SATA_SIL24=y +CONFIG_SATA_FSL=y +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# 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 +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_DUMMY=y +# 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_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=y +# 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_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM 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 is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +CONFIG_SKGE=y +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=y +# CONFIG_SKY2_DEBUG is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +CONFIG_GIANFAR=y +CONFIG_GFAR_NAPI=y +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_SFC is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# 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_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE 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=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +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=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM 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_NVRAM is not set +# 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=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# 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 +# +# CONFIG_DS1682 is not set +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# 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_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +# CONFIG_TTPCI_EEPROM is not set +# CONFIG_DVB_BUDGET_CORE is not set + +# +# Supported USB Adapters +# +# CONFIG_DVB_USB is not set +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +# CONFIG_DVB_CINERGYT2 is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_FLEXCOP is not set + +# +# Supported BT878 Adapters +# + +# +# Supported Pluto2 Adapters +# +# CONFIG_DVB_PLUTO2 is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TUA6100 is not set + +# +# DVB-T (terrestrial) frontends +# +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_TDA10048 is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_AU8522 is not set +# CONFIG_DVB_S5H1411 is not set + +# +# Digital terrestrial only tuners/PLL +# +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set + +# +# SEC control devices for DVB-S +# +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5530 is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +CONFIG_SND_INTEL8X0=y +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# ALSA PowerMac devices +# + +# +# ALSA PowerPC devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# ALSA SoC audio for Freescale SOCs +# + +# +# SoC Audio for the Texas Instruments OMAP +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_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=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_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_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_FSL=y +CONFIG_USB_EHCI_HCD_PPC_OF=y +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +CONFIG_USB_OHCI_HCD_PPC_OF_LE=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_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=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_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +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_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC 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 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# 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_RTC_DRV_PPC is not set +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_FSL_DMA=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_UIO is not set + +# +# 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 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=y +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=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW 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=y +CONFIG_VXFS_FS=m +# CONFIG_MINIX_FS is not set +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +# CONFIG_ROMFS_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 +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# 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=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=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION 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 +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM 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=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# 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=y +# 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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES 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_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# 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 +# 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_STACKOVERFLOW is not set +# 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_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG 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_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +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 is not set +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_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=y +# 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 +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 9cb8e29987a..cebea5cadbc 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -38,6 +38,12 @@ config MPC85xx_MDS help This option enables support for the MPC85xx MDS board +config MPC8536_DS + bool "Freescale MPC8536 DS" + select DEFAULT_UIMAGE + help + This option enables support for the MPC8536 DS board + config MPC85xx_DS bool "Freescale MPC85xx DS" select PPC_I8259 diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 6cea185f62b..cb3054e1001 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o +obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o obj-$(CONFIG_STX_GP3) += stx_gp3.o diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c new file mode 100644 index 00000000000..71d7c038961 --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -0,0 +1,125 @@ +/* + * MPC8536 DS Board Setup + * + * Copyright 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 + * 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 +#include + +#include +#include + +void __init mpc8536_ds_pic_init(void) +{ + struct mpic *mpic; + struct resource r; + struct device_node *np; + + np = of_find_node_by_type(np, "open-pic"); + if (np == NULL) { + printk(KERN_ERR "Could not find open-pic node\n"); + return; + } + + if (of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "Failed to map mpic register space\n"); + of_node_put(np); + return; + } + + mpic = mpic_alloc(np, r.start, + MPIC_PRIMARY | MPIC_WANTS_RESET | + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, + 0, 256, " OpenPIC "); + BUG_ON(mpic == NULL); + of_node_put(np); + + mpic_init(mpic); +} + +/* + * Setup the architecture + */ +static void __init mpc8536_ds_setup_arch(void) +{ +#ifdef CONFIG_PCI + struct device_node *np; +#endif + + if (ppc_md.progress) + ppc_md.progress("mpc8536_ds_setup_arch()", 0); + +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } + +#endif + + printk("MPC8536 DS board from Freescale Semiconductor\n"); +} + +static struct of_device_id __initdata mpc8536_ds_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + {}, +}; + +static int __init mpc8536_ds_publish_devices(void) +{ + return of_platform_bus_probe(NULL, mpc8536_ds_ids, NULL); +} +machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices); + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init mpc8536_ds_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,mpc8536ds"); +} + +define_machine(mpc8536_ds) { + .name = "MPC8536 DS", + .probe = mpc8536_ds_probe, + .setup_arch = mpc8536_ds_setup_arch, + .init_IRQ = mpc8536_ds_pic_init, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 489ca5a397b..87b0aa13ab4 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -243,6 +243,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 65953822c9c..1cf4084b51e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2171,6 +2171,8 @@ #define PCI_DEVICE_ID_MPC8544 0x0033 #define PCI_DEVICE_ID_MPC8572E 0x0040 #define PCI_DEVICE_ID_MPC8572 0x0041 +#define PCI_DEVICE_ID_MPC8536E 0x0050 +#define PCI_DEVICE_ID_MPC8536 0x0051 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 #define PCI_DEVICE_ID_MPC8610 0x7018 -- GitLab From dc320815305c5f019672d144f4c4c2710ef7732e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Jul 2008 10:58:45 +0200 Subject: [PATCH 1838/2509] cpm_uart: Support uart_wait_until_sent() Set port->fifosize to the software FIFO size, and update the port timeout when the baud rate is modified. SCC ports have an optional 32 byte hardware FIFO which is currently not taken into account, as there is no documented way to check when the FIFO becomes empty. Signed-off-by: Laurent Pinchart Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart_core.c | 6 ++++++ 1 file changed, 6 insertions(+) mode change 100755 => 100644 drivers/serial/cpm_uart/cpm_uart_core.c diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c old mode 100755 new mode 100644 index d389a76b4af..abe129cc927 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -490,6 +490,11 @@ static void cpm_uart_set_termios(struct uart_port *port, } } + /* + * Update the timeout + */ + uart_update_timeout(port, termios->c_cflag, baud); + /* * Set up parity check flag */ @@ -938,6 +943,7 @@ static int cpm_uart_init_port(struct device_node *np, pinfo->port.type = PORT_CPM; pinfo->port.ops = &cpm_uart_pops, pinfo->port.iotype = UPIO_MEM; + pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; spin_lock_init(&pinfo->port.lock); pinfo->port.irq = of_irq_to_resource(np, 0, NULL); -- GitLab From a5d28c8e64ff0bc77d38d9c19c6d8163e4c0ffaa Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Wed, 2 Jul 2008 18:06:13 +0200 Subject: [PATCH 1839/2509] powerpc/CPM: Add i2c pins to dts and board setup Initialize I2C pins on boards with CPM1/CPM2 controllers and document the i2c bus in booting-without-of. The boards don't have any I2C chips connected to the I2C bus, so unless some external chips are connected to the boards, this code is just an example of setting everything else up. Signed-off-by: Jochen Friedrich Signed-off-by: Kumar Gala --- Documentation/powerpc/booting-without-of.txt | 42 ++++++++++++++++++++ arch/powerpc/boot/dts/mpc8272ads.dts | 11 +++++ arch/powerpc/boot/dts/mpc866ads.dts | 11 +++++ arch/powerpc/boot/dts/mpc885ads.dts | 11 +++++ arch/powerpc/platforms/82xx/mpc8272_ads.c | 4 ++ arch/powerpc/platforms/8xx/mpc86xads_setup.c | 4 ++ arch/powerpc/platforms/8xx/mpc885ads_setup.c | 3 ++ 7 files changed, 86 insertions(+) diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index b68684d39f9..f6394b50943 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -2160,6 +2160,48 @@ platforms are moved over to use the flattened-device-tree model. }; }; + 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: diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts index 46e2da30c3d..d27f8a73c24 100644 --- a/arch/powerpc/boot/dts/mpc8272ads.dts +++ b/arch/powerpc/boot/dts/mpc8272ads.dts @@ -217,6 +217,17 @@ linux,network-index = <1>; fsl,cpm-command = <0x16200300>; }; + + i2c@11860 { + compatible = "fsl,mpc8272-i2c", + "fsl,cpm2-i2c"; + reg = <0x11860 0x20 0x8afc 0x2>; + interrupts = <1 8>; + interrupt-parent = <&PIC>; + fsl,cpm-command = <0x29600000>; + #address-cells = <1>; + #size-cells = <0>; + }; }; PIC: interrupt-controller@10c00 { diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts index 765e43c997d..bd700651f36 100644 --- a/arch/powerpc/boot/dts/mpc866ads.dts +++ b/arch/powerpc/boot/dts/mpc866ads.dts @@ -171,6 +171,17 @@ fsl,cpm-command = <0000>; linux,network-index = <1>; }; + + i2c@860 { + compatible = "fsl,mpc866-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>; + }; }; }; diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts index 9895043722b..b123e9f7a5a 100644 --- a/arch/powerpc/boot/dts/mpc885ads.dts +++ b/arch/powerpc/boot/dts/mpc885ads.dts @@ -215,6 +215,17 @@ fsl,cpm-command = <0x80>; linux,network-index = <2>; }; + + i2c@860 { + compatible = "fsl,mpc885-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>; + }; }; }; diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c index 7d301875198..8054c685d32 100644 --- a/arch/powerpc/platforms/82xx/mpc8272_ads.c +++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c @@ -96,6 +96,10 @@ static struct cpm_pin mpc8272_ads_pins[] = { {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, + + /* I2C */ + {3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN}, + {3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN}, }; static void __init init_ioports(void) diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c index c028a5b71bb..caaec29796b 100644 --- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c @@ -65,6 +65,10 @@ static struct cpm_pin mpc866ads_pins[] = { {CPM_PORTD, 13, CPM_PIN_OUTPUT}, {CPM_PORTD, 14, CPM_PIN_OUTPUT}, {CPM_PORTD, 15, CPM_PIN_OUTPUT}, + + /* I2C */ + {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, + {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, }; static void __init init_ioports(void) diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index 6e7ded0233f..45ed6cdc131 100644 --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c @@ -158,6 +158,9 @@ static struct cpm_pin mpc885ads_pins[] = { {CPM_PORTE, 28, CPM_PIN_OUTPUT}, {CPM_PORTE, 29, CPM_PIN_OUTPUT}, #endif + /* I2C */ + {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, + {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, }; static void __init init_ioports(void) -- GitLab From 98384c6cdd1fd593f399b6f879bae2cae70aad48 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 2 Jul 2008 11:46:20 -0500 Subject: [PATCH 1840/2509] powerpc/86xx: Refactor pic init Moved the pic initialization into its own common file and out of the board code. Also fixed the OF reference counting on the mpic node. Signed-off-by: Kumar Gala --- arch/powerpc/platforms/86xx/Makefile | 1 + arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 26 +------- arch/powerpc/platforms/86xx/mpc86xx.h | 3 +- arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 64 +----------------- arch/powerpc/platforms/86xx/pic.c | 78 ++++++++++++++++++++++ arch/powerpc/platforms/86xx/sbc8641d.c | 25 +------ 6 files changed, 86 insertions(+), 111 deletions(-) create mode 100644 arch/powerpc/platforms/86xx/pic.c diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 1b9b4a9b252..8fee37dec79 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 86xx linux kernel. # +obj-y := pic.o obj-$(CONFIG_SMP) += mpc86xx_smp.o obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_SBC8641D) += sbc8641d.o diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index eb16208b29d..30725302884 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -39,6 +39,8 @@ #include #include +#include "mpc86xx.h" + static unsigned char *pixis_bdcfg0, *pixis_arch; static struct of_device_id __initdata mpc8610_ids[] = { @@ -56,28 +58,6 @@ static int __init mpc8610_declare_of_platform_devices(void) } machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); -static void __init mpc86xx_hpcd_init_irq(void) -{ - struct mpic *mpic1; - struct device_node *np; - struct resource res; - - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); - - /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(np, res.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, - 0, 256, " MPIC "); - BUG_ON(mpic1 == NULL); - - mpic_init(mpic1); -} - #ifdef CONFIG_PCI static void __devinit quirk_uli1575(struct pci_dev *dev) { @@ -405,7 +385,7 @@ define_machine(mpc86xx_hpcd) { .name = "MPC86xx HPCD", .probe = mpc86xx_hpcd_probe, .setup_arch = mpc86xx_hpcd_setup_arch, - .init_IRQ = mpc86xx_hpcd_init_irq, + .init_IRQ = mpc86xx_init_irq, .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, .time_init = mpc86xx_time_init, diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index 525ffa1904f..08efb57559d 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h @@ -15,6 +15,7 @@ * mpc86xx_* files. Mostly for use by mpc86xx_setup(). */ -extern void __init mpc86xx_smp_init(void); +extern void mpc86xx_smp_init(void); +extern void mpc86xx_init_irq(void); #endif /* __MPC86XX_H__ */ diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index f13704aabbe..7916599c912 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -28,7 +28,6 @@ #include #include #include -#include #include @@ -45,67 +44,6 @@ #define DBG(fmt...) do { } while(0) #endif -#ifdef CONFIG_PCI -static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) -{ - unsigned int cascade_irq = i8259_irq(); - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); - desc->chip->eoi(irq); -} -#endif /* CONFIG_PCI */ - -static void __init -mpc86xx_hpcn_init_irq(void) -{ - struct mpic *mpic1; - struct device_node *np; - struct resource res; -#ifdef CONFIG_PCI - struct device_node *cascade_node = NULL; - int cascade_irq; -#endif - - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); - - /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(np, res.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 0, 256, " MPIC "); - BUG_ON(mpic1 == NULL); - - mpic_init(mpic1); - -#ifdef CONFIG_PCI - /* Initialize i8259 controller */ - for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { - cascade_node = np; - break; - } - if (cascade_node == NULL) { - printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n"); - return; - } - - cascade_irq = irq_of_parse_and_map(cascade_node, 0); - if (cascade_irq == NO_IRQ) { - printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt"); - return; - } - DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq); - - i8259_init(cascade_node, 0); - of_node_put(cascade_node); - - set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); -#endif -} - #ifdef CONFIG_PCI extern int uses_fsl_uli_m1575; extern int uli_exclude_device(struct pci_controller *hose, @@ -237,7 +175,7 @@ define_machine(mpc86xx_hpcn) { .name = "MPC86xx HPCN", .probe = mpc86xx_hpcn_probe, .setup_arch = mpc86xx_hpcn_setup_arch, - .init_IRQ = mpc86xx_hpcn_init_irq, + .init_IRQ = mpc86xx_init_irq, .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c new file mode 100644 index 00000000000..8881c5de500 --- /dev/null +++ b/arch/powerpc/platforms/86xx/pic.c @@ -0,0 +1,78 @@ +/* + * Copyright 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_PPC_I8259 +static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) +{ + unsigned int cascade_irq = i8259_irq(); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + desc->chip->eoi(irq); +} +#endif /* CONFIG_PPC_I8259 */ + +void __init mpc86xx_init_irq(void) +{ + struct mpic *mpic; + struct device_node *np; + struct resource res; +#ifdef CONFIG_PPC_I8259 + struct device_node *cascade_node = NULL; + int cascade_irq; +#endif + + /* Determine PIC address. */ + np = of_find_node_by_type(NULL, "open-pic"); + if (np == NULL) + return; + of_address_to_resource(np, 0, &res); + + mpic = mpic_alloc(np, res.start, + MPIC_PRIMARY | MPIC_WANTS_RESET | + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, + 0, 256, " MPIC "); + of_node_put(np); + BUG_ON(mpic == NULL); + + mpic_init(mpic); + +#ifdef CONFIG_PPC_I8259 + /* Initialize i8259 controller */ + for_each_node_by_type(np, "interrupt-controller") + if (of_device_is_compatible(np, "chrp,iic")) { + cascade_node = np; + break; + } + + if (cascade_node == NULL) { + printk(KERN_DEBUG "Could not find i8259 PIC\n"); + return; + } + + cascade_irq = irq_of_parse_and_map(cascade_node, 0); + if (cascade_irq == NO_IRQ) { + printk(KERN_ERR "Failed to map cascade interrupt\n"); + return; + } + + i8259_init(cascade_node, 0); + of_node_put(cascade_node); + + set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); +#endif +} diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 510a06ef0b5..00e6fad3b3c 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -37,29 +37,6 @@ #include "mpc86xx.h" -static void __init -sbc8641_init_irq(void) -{ - struct mpic *mpic1; - struct device_node *np; - struct resource res; - - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); - - /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(np, res.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 0, 256, " MPIC "); - of_node_put(np); - BUG_ON(mpic1 == NULL); - - mpic_init(mpic1); -} - static void __init sbc8641_setup_arch(void) { @@ -151,7 +128,7 @@ define_machine(sbc8641) { .name = "SBC8641D", .probe = sbc8641_probe, .setup_arch = sbc8641_setup_arch, - .init_IRQ = sbc8641_init_irq, + .init_IRQ = mpc86xx_init_irq, .show_cpuinfo = sbc8641_show_cpuinfo, .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, -- GitLab From ddb107e98b58ee280e99317cfd6efd16112678f2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 27 Jun 2008 08:03:13 -0500 Subject: [PATCH 1841/2509] powerpc/booke: don't reinitialize time base For some reason long ago I decided that we should zero out the time base when we calibrate the decrementer. The problem is that this can be harmful in SMP systems where the firmware has already synchronized the time bases on the various cores. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/time.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index c73fc33aa81..eb938808ddf 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -742,10 +742,6 @@ void __init generic_calibrate_decr(void) } #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); -- GitLab From a64887eb0a376d412cfa07a52728fb3f56cf9d6c Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Mon, 16 Jun 2008 15:36:17 -0700 Subject: [PATCH 1842/2509] powerpc/85xx: publish of device for cds platforms Publish the devices listed in dts under SOC as of_device for 85xx_cds platform. The devices are needed by the 85xx EDAC driver. Signed-off-by: Dave Jiang Signed-off-by: Kumar Gala --- arch/powerpc/platforms/85xx/mpc85xx_cds.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 8b1de7884be..50d7ea8f922 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -335,6 +336,19 @@ static int __init mpc85xx_cds_probe(void) return of_flat_dt_is_compatible(root, "MPC85xxCDS"); } +static struct of_device_id __initdata of_bus_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .compatible = "simple-bus", }, + {}, +}; + +static int __init declare_of_platform_devices(void) +{ + return of_platform_bus_probe(NULL, of_bus_ids, NULL); +} +machine_device_initcall(mpc85xx_cds, declare_of_platform_devices); + define_machine(mpc85xx_cds) { .name = "MPC85xx CDS", .probe = mpc85xx_cds_probe, -- GitLab From d8267c1a36864fc30a2ce01f4349a8f2931ae741 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 27 Jun 2008 11:26:26 -0500 Subject: [PATCH 1843/2509] powerpc: Add 82xx/83xx/86xx to 6xx Multiplatform There isn't any reason at this point that we can't build 82xx, 83xx & 86xx support in with the other 6xx based boards. Twiddle the Kconfigs to allow this. This allows us to remove the machine type selection for related to 6xx. Signed-off-by: Kumar Gala --- arch/powerpc/platforms/82xx/Kconfig | 11 +++++----- arch/powerpc/platforms/83xx/Kconfig | 10 +++++---- arch/powerpc/platforms/86xx/Kconfig | 16 +++++++++----- arch/powerpc/platforms/Kconfig | 33 +++-------------------------- 4 files changed, 26 insertions(+), 44 deletions(-) diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig index 917ac889155..1c8034bfa79 100644 --- a/arch/powerpc/platforms/82xx/Kconfig +++ b/arch/powerpc/platforms/82xx/Kconfig @@ -1,7 +1,8 @@ -choice - prompt "82xx Board Type" - depends on PPC_82xx - default MPC8272_ADS +menuconfig PPC_82xx + bool "82xx-based boards (PQ II)" + depends on 6xx && PPC_MULTIPLATFORM + +if PPC_82xx config MPC8272_ADS bool "Freescale MPC8272 ADS" @@ -36,7 +37,7 @@ config EP8248E This board is also resold by Freescale as the QUICCStart MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE. -endchoice +endif config PQ2ADS bool diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index fe75b2ac3c9..27d9bf86de0 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -1,10 +1,12 @@ -menuconfig MPC83xx - bool "83xx Board Type" - depends on PPC_83xx +menuconfig PPC_83xx + bool "83xx-based boards" + depends on 6xx && PPC_MULTIPLATFORM select PPC_UDBG_16550 select PPC_INDIRECT_PCI + select FSL_SOC + select IPIC -if MPC83xx +if PPC_83xx config MPC831x_RDB bool "Freescale MPC831x RDB" diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 053f49a1dca..80a81e02bb5 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -1,7 +1,13 @@ -choice - prompt "86xx Board Type" - depends on PPC_86xx - default MPC8641_HPCN +config PPC_86xx +menuconfig PPC_86xx + bool "86xx-based boards" + depends on 6xx && PPC_MULTIPLATFORM + select FSL_SOC + select ALTIVEC + help + The Freescale E600 SoCs have 74xx cores. + +if PPC_86xx config MPC8641_HPCN bool "Freescale MPC8641 HPCN" @@ -24,7 +30,7 @@ config MPC8610_HPCD help This option enables support for the MPC8610 HPCD board. -endchoice +endif config MPC8641 bool diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 87454c52697..690c1f46e69 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -1,36 +1,9 @@ menu "Platform support" -choice - prompt "Machine type" - depends on PPC64 || 6xx - default PPC_MULTIPLATFORM - config PPC_MULTIPLATFORM - bool "Generic desktop/server/laptop" - help - Select this option if configuring for an IBM pSeries or - RS/6000 machine, an Apple machine, or a PReP, CHRP, - Maple or Cell-based machine. - -config PPC_82xx - bool "Freescale 82xx" - depends on 6xx - -config PPC_83xx - bool "Freescale 83xx" - depends on 6xx - select FSL_SOC - select MPC83xx - select IPIC - -config PPC_86xx - bool "Freescale 86xx" - depends on 6xx - select FSL_SOC - select ALTIVEC - help - The Freescale E600 SoCs have 74xx cores. -endchoice + bool + depends on PPC64 || 6xx + default y config CLASSIC32 def_bool y -- GitLab From b93eeba49efb30f88a83fc97ad22c255605654a1 Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Tue, 8 Jul 2008 09:21:08 +0800 Subject: [PATCH 1844/2509] powerpc/85xx: Minor fixes for 85xxds and 8536ds board. Remove the "uninitialized use" compile warning and avoid potential runtime issue. Signed-off-by: Jason Jin Signed-off-by: Kumar Gala --- arch/powerpc/platforms/85xx/mpc8536_ds.c | 2 +- arch/powerpc/platforms/85xx/mpc85xx_ds.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 71d7c038961..6b846aa1ced 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -36,7 +36,7 @@ void __init mpc8536_ds_pic_init(void) struct resource r; struct device_node *np; - np = of_find_node_by_type(np, "open-pic"); + np = of_find_node_by_type(NULL, "open-pic"); if (np == NULL) { printk(KERN_ERR "Could not find open-pic node\n"); return; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 8b2d63d4264..25f41cd2d33 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -64,7 +64,7 @@ void __init mpc85xx_ds_pic_init(void) int cascade_irq; #endif - np = of_find_node_by_type(np, "open-pic"); + np = of_find_node_by_type(NULL, "open-pic"); if (np == NULL) { printk(KERN_ERR "Could not find open-pic node\n"); return; -- GitLab From d0fc2eaaf4c56a95f5ed29b6bfb609e19714fc16 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 7 Jul 2008 11:28:33 -0500 Subject: [PATCH 1845/2509] powerpc/fsl: Refactor device bindings Moved Freescale SoC related bindings out of booting-without-of.txt and into their own files. Signed-off-by: Kumar Gala --- Documentation/powerpc/booting-without-of.txt | 1218 +---------------- .../powerpc/dts-bindings/fsl/board.txt | 29 + .../powerpc/dts-bindings/fsl/cpm_qe/cpm.txt | 67 + .../dts-bindings/fsl/cpm_qe/cpm/brg.txt | 21 + .../dts-bindings/fsl/cpm_qe/cpm/i2c.txt | 41 + .../dts-bindings/fsl/cpm_qe/cpm/pic.txt | 18 + .../dts-bindings/fsl/cpm_qe/cpm/usb.txt | 15 + .../dts-bindings/fsl/cpm_qe/network.txt | 45 + .../powerpc/dts-bindings/fsl/cpm_qe/qe.txt | 58 + .../dts-bindings/fsl/cpm_qe/qe/firmware.txt | 24 + .../dts-bindings/fsl/cpm_qe/qe/par_io.txt | 51 + .../dts-bindings/fsl/cpm_qe/qe/pincfg.txt | 60 + .../dts-bindings/fsl/cpm_qe/qe/ucc.txt | 70 + .../dts-bindings/fsl/cpm_qe/qe/usb.txt | 22 + .../dts-bindings/fsl/cpm_qe/serial.txt | 21 + .../powerpc/dts-bindings/fsl/diu.txt | 18 + .../powerpc/dts-bindings/fsl/dma.txt | 127 ++ .../powerpc/dts-bindings/fsl/gtm.txt | 31 + .../powerpc/dts-bindings/fsl/guts.txt | 25 + .../powerpc/dts-bindings/fsl/i2c.txt | 32 + .../powerpc/dts-bindings/fsl/lbc.txt | 35 + .../powerpc/dts-bindings/fsl/msi-pic.txt | 36 + .../powerpc/dts-bindings/fsl/sata.txt | 29 + .../powerpc/dts-bindings/fsl/spi.txt | 24 + .../powerpc/dts-bindings/fsl/ssi.txt | 38 + .../powerpc/dts-bindings/fsl/tsec.txt | 69 + .../powerpc/dts-bindings/fsl/usb.txt | 59 + 27 files changed, 1077 insertions(+), 1206 deletions(-) create mode 100644 Documentation/powerpc/dts-bindings/fsl/board.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/diu.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/dma.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/gtm.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/guts.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/i2c.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/lbc.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/msi-pic.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/sata.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/spi.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/ssi.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/tsec.txt create mode 100644 Documentation/powerpc/dts-bindings/fsl/usb.txt diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index f6394b50943..de2e5c05d6e 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -41,27 +41,12 @@ Table of Contents VI - System-on-a-chip devices and nodes 1) Defining child nodes of an SOC 2) Representing devices without a current OF specification - a) MDIO IO device - b) Gianfar-compatible ethernet nodes - c) PHY nodes - d) Interrupt controllers - e) I2C - f) Freescale SOC USB controllers - g) Freescale SOC SEC Security Engines - h) Board Control and Status (BCSR) - i) Freescale QUICC Engine module (QE) - j) CFI or JEDEC memory-mapped NOR flash - k) Global Utilities Block - l) Freescale Communications Processor Module - m) Chipselect/Local Bus - n) 4xx/Axon EMAC ethernet nodes - o) Xilinx IP cores - p) Freescale Synchronous Serial Interface - q) USB EHCI controllers - r) Freescale Display Interface Unit - s) Freescale on board FPGA - t) Freescael MSI interrupt controller - u) Freescale General-purpose Timers Module + a) PHY nodes + b) Interrupt controllers + c) CFI or JEDEC memory-mapped NOR flash + d) 4xx/Axon EMAC ethernet nodes + e) Xilinx IP cores + f) USB EHCI controllers VII - Marvell Discovery mv64[345]6x System Controller chips 1) The /system-controller node @@ -1250,80 +1235,7 @@ descriptions for the SOC devices for which new nodes have been defined; this list will expand as more and more SOC-containing platforms are moved over to use the flattened-device-tree model. - a) 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 { - ...... - }; - }; - - - b) 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> - }; - - - - 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 00000000000..74ae6f1cd2d --- /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 00000000000..088fc471e03 --- /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 00000000000..4c7d45eaf02 --- /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 00000000000..87bc6048667 --- /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 00000000000..8e3ee168161 --- /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 00000000000..74bfda4bb82 --- /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 00000000000..0e426944658 --- /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 00000000000..78790d58dc2 --- /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 00000000000..6c238f59b2a --- /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 00000000000..60984260207 --- /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 00000000000..c5b43061db3 --- /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 00000000000..e47734bee3f --- /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 00000000000..c8f44d6bcbc --- /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 00000000000..b35f3482e3e --- /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 00000000000..deb35de7098 --- /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 00000000000..86826df00e6 --- /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 00000000000..9a33efded4b --- /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 00000000000..9e7a2417dac --- /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 00000000000..d0ab33e21fe --- /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 00000000000..3300fec501c --- /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 00000000000..b26b91992c5 --- /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 00000000000..b46bcf46c3d --- /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 00000000000..e7d9a344c4f --- /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 00000000000..d100555d488 --- /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 00000000000..583ef6b56c4 --- /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 00000000000..b0015240269 --- /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"; + }; -- GitLab From 3fd44736db9a5bf33e4a216b9cd43c9cfd57c459 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 8 Jul 2008 19:13:33 -0500 Subject: [PATCH 1846/2509] 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 --- .../powerpc/dts-bindings/fsl/sec.txt | 68 +++++++++++++++++++ arch/powerpc/boot/dts/mpc8272ads.dts | 21 ++---- arch/powerpc/boot/dts/mpc8313erdb.dts | 15 ++-- arch/powerpc/boot/dts/mpc8315erdb.dts | 15 ++-- arch/powerpc/boot/dts/mpc832x_mds.dts | 15 ++-- arch/powerpc/boot/dts/mpc832x_rdb.dts | 15 ++-- arch/powerpc/boot/dts/mpc8349emitx.dts | 12 ++-- arch/powerpc/boot/dts/mpc8349emitxgp.dts | 12 ++-- arch/powerpc/boot/dts/mpc834x_mds.dts | 15 ++-- arch/powerpc/boot/dts/mpc836x_mds.dts | 13 ++-- arch/powerpc/boot/dts/mpc8377_mds.dts | 13 ++-- arch/powerpc/boot/dts/mpc8377_rdb.dts | 14 ++-- arch/powerpc/boot/dts/mpc8378_mds.dts | 13 ++-- arch/powerpc/boot/dts/mpc8378_rdb.dts | 14 ++-- arch/powerpc/boot/dts/mpc8379_mds.dts | 13 ++-- arch/powerpc/boot/dts/mpc8379_rdb.dts | 14 ++-- arch/powerpc/boot/dts/mpc8536ds.dts | 12 ++++ arch/powerpc/boot/dts/mpc8541cds.dts | 11 +++ arch/powerpc/boot/dts/mpc8544ds.dts | 11 +++ arch/powerpc/boot/dts/mpc8548cds.dts | 11 +++ arch/powerpc/boot/dts/mpc8555cds.dts | 11 +++ arch/powerpc/boot/dts/mpc8568mds.dts | 14 ++-- arch/powerpc/boot/dts/mpc8572ds.dts | 12 ++++ arch/powerpc/boot/dts/sbc8349.dts | 14 ++-- arch/powerpc/boot/dts/sbc8548.dts | 11 +++ arch/powerpc/boot/dts/tqm8541.dts | 11 +++ arch/powerpc/boot/dts/tqm8555.dts | 11 +++ 27 files changed, 268 insertions(+), 143 deletions(-) create mode 100644 Documentation/powerpc/dts-bindings/fsl/sec.txt diff --git a/Documentation/powerpc/dts-bindings/fsl/sec.txt b/Documentation/powerpc/dts-bindings/fsl/sec.txt new file mode 100644 index 00000000000..2b6f2d45c45 --- /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 d27f8a73c24..2a1929acaab 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 b2068430a06..3664fb58402 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 a40e8064d42..f704513fb93 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 b5968b6c8a2..7345743d3d9 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 a798d8639a7..e74c045a0f8 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 fc0f4c918c7..8dfab566258 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 e6afb1d1e19..49ca3497eef 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 9c75c7c69e2..ba586cb7afb 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 8e33b155f11..3701dae1ee0 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 49a38cb95b5..0a700cb5f61 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 1f453879030..ed137aa83d5 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 99ad49d4f13..29c8c76a58f 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 44e34d3f21c..34a7f2f935e 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 980be813627..d641a8985ea 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 eeedf588488..e4d7030d50e 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 98ad27a2dde..02cfa24a169 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 21ad71b825c..c4469f19ff8 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 6cf533f4b5f..7d3829d3495 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 d1fa6bbfaea..d84466bb7ec 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 6fc8059b5a0..e03a7800628 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 be9a289c0d6..9c30a34821d 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 cb06325f0b7..08c61e3daec 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 5b76bb26085..45f789b5670 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 21cbacb1000..333552b4e90 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 d083a648a81..d76441ec5dc 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 96b0b94ad92..6f7ea59c484 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>; -- GitLab From 1c776bf87c855a6e823e13c3667f0cf7c14635bd Mon Sep 17 00:00:00 2001 From: Krzysztof Oledzki Date: Wed, 4 Jun 2008 03:40:17 +0200 Subject: [PATCH 1847/2509] 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 --- arch/x86/kernel/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index d89a648fe71..06e1fd6be83 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, -- GitLab From 4c2a997c34c0aa952ba9c247b0c2043526054919 Mon Sep 17 00:00:00 2001 From: Joe Buehler Date: Mon, 9 Jun 2008 08:55:20 -0400 Subject: [PATCH 1848/2509] 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 --- arch/x86/kernel/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 06e1fd6be83..f327abafe3e 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, -- GitLab From 7798ed0f57b4d137e660fbf5be1e1528e40f89ac Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 14 Jul 2008 19:55:03 +1000 Subject: [PATCH 1849/2509] 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 --- arch/powerpc/kernel/stacktrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index 9861f17258d..3cf0d94ba34 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -12,6 +12,7 @@ #include #include +#include #include /* -- GitLab From ae8547b0a9e5d718ce272ddc48f91703a0f52a0b Mon Sep 17 00:00:00 2001 From: Hans Reiser Date: Wed, 7 May 2008 15:48:57 +0300 Subject: [PATCH 1850/2509] 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 --- fs/fs-writeback.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ae45f77765c..16519fe1399 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); } /* -- GitLab From 4ee6afd34409d296782a5b667d7991b1050e910a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 7 May 2008 21:01:30 +0300 Subject: [PATCH 1851/2509] 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 --- fs/fs-writeback.c | 11 +++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 16519fe1399..25adfc3c693 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 d8e2762ed14..f9d2aab47ed 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 *); -- GitLab From 2d62f488585405bc9108c47cb06957397cfd1059 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jan 2008 17:25:00 +0200 Subject: [PATCH 1852/2509] do_mounts: allow UBI root device name Similarly to MTD devices, allow UBI devices. Signed-off-by: Adrian Hunter --- init/do_mounts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init/do_mounts.c b/init/do_mounts.c index 660c1e50c91..a1de1bf3d6b 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; } -- GitLab From 3bf2e77453a87c22eb57ed4926760ac131c84459 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 13 Jul 2008 21:18:02 -0700 Subject: [PATCH 1853/2509] 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 --- arch/x86/kernel/acpi/sleep.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 36af01f029e..130711f1454 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); -- GitLab From 065cb3dfe24978651caedfa54da585388ad15dde Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 14 Jul 2008 11:44:26 -0700 Subject: [PATCH 1854/2509] 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 --- arch/x86/kernel/acpi/sleep.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 130711f1454..41bb130c31d 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); -- GitLab From 7daf705f362e349983e92037a198b8821db198af Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jul 2008 12:12:53 -0700 Subject: [PATCH 1855/2509] 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 --- arch/x86/kernel/traps_64.c | 25 +------------------------ mm/slub.c | 5 ++--- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index adff76ea97c..f1a95d10595 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 315c392253c..5f6e2c4a2ba 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) -- GitLab From 341c2c958ec7bdd9f54733a8b0b432fe76842a82 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:51 +0900 Subject: [PATCH 1856/2509] 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 --- drivers/ata/libata-core.c | 44 +++++++++++++++++++-------------------- drivers/ata/libata-eh.c | 33 +++++++++++++++-------------- drivers/ata/libata-pmp.c | 3 ++- drivers/ata/libata-sff.c | 15 ++++++------- drivers/ata/pata_bf54x.c | 6 +++--- drivers/ata/pata_scc.c | 2 +- include/linux/libata.h | 26 ++++++++++++++--------- 7 files changed, 68 insertions(+), 61 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 303fc0d2b97..c5c3b1b516e 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 7894d83ea1e..08dd07f1000 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 7daf4c0f621..63691d77ac4 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 c0908c22548..304fdc6f1dc 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 55516103626..d3932901a3b 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 bbf5aa345e6..16673d16857 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 e57e5d08312..94110b652b3 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 -- GitLab From 0a2c0f56159999e20015241d3b8fa89b1ab14309 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:52 +0900 Subject: [PATCH 1857/2509] 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 --- drivers/ata/libata-eh.c | 38 ++++++++++++++++++++------------------ drivers/ata/libata-pmp.c | 10 ---------- include/linux/libata.h | 2 ++ 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 08dd07f1000..5b5ae631ed0 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 63691d77ac4..b65db309c18 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 94110b652b3..9058c2a325a 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 -- GitLab From d8af0eb6046c56e7238171ca420622541db24926 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:53 +0900 Subject: [PATCH 1858/2509] 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 --- drivers/ata/libata-eh.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5b5ae631ed0..83d1451fa71 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)) -- GitLab From 87fbc5a060faf2394bee88a93519f9b9d434727c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:54 +0900 Subject: [PATCH 1859/2509] 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 --- drivers/ata/libata-core.c | 16 ++++- drivers/ata/libata-eh.c | 121 +++++++++++++++++++++++++++++++++++++- drivers/ata/libata.h | 2 + include/linux/libata.h | 8 ++- 4 files changed, 142 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c5c3b1b516e..9bef1a84fe3 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 83d1451fa71..d5f03a6e333 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 1cf803adbc9..f6f9c28ec7f 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 9058c2a325a..035f8e1cd0a 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; -- GitLab From 18f7ba4c2f4be6b37d925931f04d6cc28d88d1ee Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Tue, 3 Jun 2008 10:33:55 -0700 Subject: [PATCH 1860/2509] libata/ahci: enclosure management support Add Enclosure Management support to libata and ahci. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 321 +++++++++++++++++++++++++++++++++++++- drivers/ata/libata-scsi.c | 79 ++++++++++ include/linux/libata.h | 21 +++ 3 files changed, 419 insertions(+), 2 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5e6468a7ca4..65d4e968feb 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 57a43649a46..b578b11caa7 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 035f8e1cd0a..5b247b8a6b3 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 */ -- GitLab From ec6add99307d5149e17f6e358f19f0205b622407 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 23 Jun 2008 11:01:31 +0200 Subject: [PATCH 1861/2509] [libata] sata_svw: update code comments relating to data corruption Signed-off-by: Pavel Machek Signed-off-by: Jeff Garzik --- drivers/ata/sata_svw.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 16aa6839aa5..fb13b82aacb 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); } -- GitLab From 3eabddb8ed4f488664ff5d67968392bb424836a3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 10 Jun 2008 18:28:05 +0900 Subject: [PATCH 1862/2509] 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 --- drivers/ata/libata-eh.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index d5f03a6e333..58bdc538d22 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 -- GitLab From 6ad67403da47e833d9e418caf7f28295c9472e11 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 18 Jun 2008 17:16:43 -0700 Subject: [PATCH 1863/2509] 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 --- drivers/ata/pata_legacy.c | 10 ++++------ drivers/ata/pata_qdi.c | 2 +- drivers/ata/pata_winbond.c | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index fe7cc8ed4ea..bc037ffce20 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 97e5b090d7c..63b7a1c165a 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 474528f8fe3..a7606b044a6 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); -- GitLab From 1e9dbc9291738149577cc488fd441f061815e02e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 19 Jun 2008 13:13:38 -0600 Subject: [PATCH 1864/2509] [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 --- drivers/ata/libata-scsi.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b578b11caa7..479c29e2e25 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; -- GitLab From 24920c8a6358bf5532f1336b990b1c0fe2b599ee Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 4 Jul 2008 13:32:17 +0800 Subject: [PATCH 1865/2509] 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 --- drivers/ata/ahci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 65d4e968feb..4ff3f03cf97 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); -- GitLab From 2640d7c0b8d5d9d9ee303b8cd09f5124176f6239 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 6 Jul 2008 09:23:20 -0400 Subject: [PATCH 1866/2509] 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 --- drivers/ata/ahci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 4ff3f03cf97..dc7596f028b 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); -- GitLab From 7f101a97866e2687a455ecffeb96bcf317c8482a Mon Sep 17 00:00:00 2001 From: Dave Young Date: Mon, 14 Jul 2008 22:38:19 +0200 Subject: [PATCH 1867/2509] i2c: Use class_for_each_device Use class_for_each_device for iteration. Signed-off-by: Dave Young Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 92 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d0175f4f8fc..f489683fd15 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); -- GitLab From cc99ff70c7ad36e01db545a81a8594474964f918 Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: [PATCH 1868/2509] 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 --- drivers/i2c/busses/i2c-davinci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 7ecbfc429b1..7fdbca17d4a 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); -- GitLab From d868caa177d4487ce1935926498f542a8f67c1cf Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: [PATCH 1869/2509] 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 --- drivers/i2c/busses/i2c-davinci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 7fdbca17d4a..85097fdc75e 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; } -- GitLab From 0ab56e20674b41dd0203d16b602aac8d9d26a70a Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: [PATCH 1870/2509] 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 --- drivers/i2c/busses/i2c-davinci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 85097fdc75e..c56f8fe4efe 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; -- GitLab From 5a0d5f5ffa5d294d895ef54fc220c6182db63998 Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: [PATCH 1871/2509] 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 --- drivers/i2c/busses/i2c-davinci.c | 62 ++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c56f8fe4efe..16085729695 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: -- GitLab From 2e7437879897a4185bd84478a0451e5367dee7ed Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: [PATCH 1872/2509] 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 --- drivers/i2c/busses/i2c-davinci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 16085729695..af3846eda98 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); -- GitLab From 279e902445557897707d325182916a6e28ba80de Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: [PATCH 1873/2509] 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 --- drivers/i2c/busses/Kconfig | 13 ++ drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-nforce2-s4985.c | 257 +++++++++++++++++++++++++ drivers/i2c/busses/i2c-nforce2.c | 16 ++ 4 files changed, 287 insertions(+) create mode 100644 drivers/i2c/busses/i2c-nforce2-s4985.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 48438cc5d0c..00d76e13588 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 e8c882a5ea6..8b0a8c25790 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 00000000000..6a8995dfd0b --- /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 43c9f8df950..f95efff9b3d 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); -- GitLab From 20a9b6e7c303f2a6f9afe17c0997bc9a3c734442 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: [PATCH 1874/2509] 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 --- Documentation/feature-removal-schedule.txt | 7 - Documentation/i2c/busses/i2c-i810 | 47 --- Documentation/i2c/busses/i2c-prosavage | 23 -- Documentation/i2c/busses/i2c-savage4 | 26 -- drivers/i2c/busses/Kconfig | 52 ---- drivers/i2c/busses/Makefile | 3 - drivers/i2c/busses/i2c-i810.c | 260 ----------------- drivers/i2c/busses/i2c-prosavage.c | 325 --------------------- drivers/i2c/busses/i2c-savage4.c | 185 ------------ include/linux/i2c-id.h | 1 - 10 files changed, 929 deletions(-) delete mode 100644 Documentation/i2c/busses/i2c-i810 delete mode 100644 Documentation/i2c/busses/i2c-prosavage delete mode 100644 Documentation/i2c/busses/i2c-savage4 delete mode 100644 drivers/i2c/busses/i2c-i810.c delete mode 100644 drivers/i2c/busses/i2c-prosavage.c delete mode 100644 drivers/i2c/busses/i2c-savage4.c diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 46ece3fba6f..65a1482457a 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 778210ee158..00000000000 --- 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 70368790251..00000000000 --- 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 6ecceab618d..00000000000 --- 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 00d76e13588..b7cce921183 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 8b0a8c25790..81bb407d24c 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 42e8d94c276..00000000000 --- 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 07c1f1e27df..00000000000 --- 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 8adf4abaa03..00000000000 --- 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 580acc93903..988e566d3ed 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 */ -- GitLab From 4d2bee582be1e9da76e0717bad0cfd988c2a5921 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: [PATCH 1875/2509] 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 --- drivers/i2c/busses/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b7cce921183..37f5b84e0e9 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. -- GitLab From 81fded1f79771809059bdfa721ae5ab9114af545 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: [PATCH 1876/2509] 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 --- Documentation/i2c/fault-codes | 127 ++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 Documentation/i2c/fault-codes diff --git a/Documentation/i2c/fault-codes b/Documentation/i2c/fault-codes new file mode 100644 index 00000000000..045765c0b9b --- /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. + -- GitLab From 75415490d6adc1aecbf0cade0785b007957d0cfe Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: [PATCH 1877/2509] i2c-core: Remove needless include i2c-core doesn't use seq files, so doesn't need to include . Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f489683fd15..bb5c215a24e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- GitLab From 24a5bb7b1838dc4524dd353224e2aa09c22cac3b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: [PATCH 1878/2509] 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 --- Documentation/i2c/writing-clients | 8 +-- drivers/i2c/i2c-core.c | 97 +++++++++++++++++-------------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index d4cd4126d1a..ba5d1971f35 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 bb5c215a24e..937f1dcbf3d 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) -- GitLab From f5b728a164b22ec38a5657ebe038def36ffae98b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: [PATCH 1879/2509] 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 --- drivers/i2c/busses/Kconfig | 749 ++++++++++++++++++------------------ drivers/i2c/busses/Makefile | 53 ++- 2 files changed, 414 insertions(+), 388 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 37f5b84e0e9..2b0874b0ad1 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 81bb407d24c..48a6a5bddc5 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 -- GitLab From 67c2e66571c383404a5acd08189194da660da942 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: [PATCH 1880/2509] 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 --- Documentation/i2c/smbus-protocol | 4 ++-- Documentation/i2c/writing-clients | 14 +++++++------- drivers/i2c/i2c-core.c | 7 ------- include/linux/i2c.h | 1 - 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol index 03f08fb491c..24bfb65da17 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 ba5d1971f35..63722d3c9cd 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 937f1dcbf3d..3695a4a1ab7 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 8dc73013219..b3695f353f7 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); -- GitLab From ae7193f7fa3e1735ab70807eb6e35a2a6575623f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: [PATCH 1881/2509] i2c: Update stray references to smbus_access That function is actually named i2c_smbus_xfer. Signed-off-by: Jean Delvare --- include/linux/i2c.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index b3695f353f7..7c36d5188d3 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 -- GitLab From a1cdedac634eef81f747078bf1c27ad36ab13553 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: [PATCH 1882/2509] 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 --- drivers/i2c/i2c-core.c | 133 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 3695a4a1ab7..527d51319f3 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; } -- GitLab From 6ea438ec8da4ec56bf415f5ea360e6b0cb59c6c3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: [PATCH 1883/2509] 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 --- drivers/i2c/i2c-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 527d51319f3..b995502400b 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); -- GitLab From 97140342e69d479a3ad82bfd4c154c0b08fe3eea Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: [PATCH 1884/2509] 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 --- drivers/i2c/algos/i2c-algo-bit.c | 4 +-- drivers/i2c/busses/i2c-ali1535.c | 22 ++++++------- drivers/i2c/busses/i2c-ali1563.c | 23 +++++++++---- drivers/i2c/busses/i2c-ali15x3.c | 19 ++++++----- drivers/i2c/busses/i2c-amd756-s4882.c | 4 +-- drivers/i2c/busses/i2c-amd756.c | 18 +++++----- drivers/i2c/busses/i2c-amd8111.c | 47 ++++++++++++++++++--------- drivers/i2c/busses/i2c-i801.c | 44 +++++++++++++------------ drivers/i2c/busses/i2c-nforce2.c | 25 +++++++------- drivers/i2c/busses/i2c-piix4.c | 20 +++++++----- drivers/i2c/busses/i2c-sis5595.c | 19 ++++++----- drivers/i2c/busses/i2c-sis630.c | 47 +++++++++++++++------------ drivers/i2c/busses/i2c-sis96x.c | 23 ++++++------- drivers/i2c/busses/i2c-stub.c | 4 +-- drivers/i2c/busses/i2c-viapro.c | 20 +++++++----- 15 files changed, 191 insertions(+), 148 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 35812823787..eb8f72ca02f 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 f14372ac2fc..c21e4d96382 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 6b68074e518..30bd3ee7038 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 93bf87d7096..3d752561dc3 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 c38a0a11220..2f150e33c74 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 43508d61eb7..3d5bcb65e9e 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 5d1a27ef250..a4f687915de 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 b0f771fe432..7d6d9dfcc58 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 f95efff9b3d..081fdf3393f 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 ac916596858..dc76c0e2dc6 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 9ca8f9155f9..328441bb547 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 3765dd7f450..c4cc5eddf50 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 dc235bb8e24..29757b2e11d 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 d08eeec5391..e37ccd80f77 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 77b13d027f8..7628fe8e094 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) -- GitLab From fa63cd56d2f09806169307d761e8f430e23bc09b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: [PATCH 1885/2509] 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 --- drivers/i2c/busses/i2c-piix4.c | 41 +++++++++++++--------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index dc76c0e2dc6..77aaa5fe5e3 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); -- GitLab From ac7fc4fb2b6a126af8d07f46500440c9641976cf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: [PATCH 1886/2509] 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 --- drivers/i2c/busses/i2c-ali1535.c | 8 ++++---- drivers/i2c/busses/i2c-ali1563.c | 8 ++++---- drivers/i2c/busses/i2c-ali15x3.c | 6 +++--- drivers/i2c/busses/i2c-amd756.c | 8 +++----- drivers/i2c/busses/i2c-i801.c | 1 - drivers/i2c/busses/i2c-piix4.c | 6 +++--- drivers/i2c/busses/i2c-sis630.c | 5 ++--- drivers/i2c/busses/i2c-sis96x.c | 8 +------- drivers/i2c/busses/i2c-taos-evm.c | 5 ++--- drivers/i2c/busses/i2c-viapro.c | 2 +- 10 files changed, 23 insertions(+), 34 deletions(-) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index c21e4d96382..704436cdec8 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 30bd3ee7038..da5a382eee9 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 3d752561dc3..7b029b147a8 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 3d5bcb65e9e..f0baea62067 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 7d6d9dfcc58..213119211e5 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 77aaa5fe5e3..2bde47509e1 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 c4cc5eddf50..d7e6ff3e018 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 29757b2e11d..cde8e588036 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 de9db49e54d..224aa12ee7c 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 7628fe8e094..c611905df00 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; } -- GitLab From c80ebe7987931ec4e80abc33ebf8aa2dad0d3763 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: [PATCH 1887/2509] 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 --- drivers/i2c/algos/i2c-algo-pca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index e954a20b97a..d50b329a3c9 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); -- GitLab From 7650da023eb05426812bbf8999b69dc93fee67ab Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: [PATCH 1888/2509] 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 --- drivers/i2c/busses/i2c-pca-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 9d75f51e8f0..6bb15ad0a6b 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; -- GitLab From 6a03cd931196673634b58c955d2f9d42da602045 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: [PATCH 1889/2509] 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 --- drivers/i2c/i2c-core.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b995502400b..1a71645038f 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, -- GitLab From f7050bd716047a4dfec7d061e28df7ffd6815ebd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: [PATCH 1890/2509] i2c: Simplify i2c_del_driver() i2c_del_driver() can be simplified a bit. Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1a71645038f..e06067ebd20 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); -- GitLab From 5bc1200852c3dfc312481f57622f48b289ac802e Mon Sep 17 00:00:00 2001 From: Alek Du Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: [PATCH 1891/2509] 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 --- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-isch.c | 336 ++++++++++++++++++++++++++++++++++ 3 files changed, 347 insertions(+) create mode 100644 drivers/i2c/busses/i2c-isch.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 2b0874b0ad1..56b6f29c9a3 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 48a6a5bddc5..cbeac7dc9bf 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 00000000000..c9cd46b2269 --- /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); -- GitLab From 77e38bffe0fcaa48f0be68eaa1de4a59d1fd93ad Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: [PATCH 1892/2509] 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 --- drivers/i2c/i2c-dev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c81c2..e96d9869678 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, }; -- GitLab From 61045dbe9d8d81b1bae4dc1e9482d389ca99edc1 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: [PATCH 1893/2509] 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 --- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-cpm.c | 745 +++++++++++++++++++++++++++++++++++ 3 files changed, 756 insertions(+) create mode 100644 drivers/i2c/busses/i2c-cpm.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 56b6f29c9a3..6ee997b2817 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 cbeac7dc9bf..97dbfa2107f 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 00000000000..1c955a82dcc --- /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"); -- GitLab From 3b270804a9345e4a0c493889f98e838692f7bc9b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: [PATCH 1894/2509] 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 --- drivers/i2c/busses/i2c-cpm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 1c955a82dcc..53af744a91c 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); -- GitLab From 0d2b405a628309310b4fc02b26d713b855ad5f68 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: [PATCH 1895/2509] i2c: Add MAINTAINER entry for i2c-cpm Signed-off-by: Jochen Friedrich Signed-off-by: Jean Delvare --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 56a2f678019..dd20fe31ea4 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 -- GitLab From c1b6b4f2342d073698dfc2547240c35045a1d00e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: [PATCH 1896/2509] 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 --- drivers/video/fb_ddc.c | 1 + drivers/video/intelfb/intelfb_i2c.c | 12 +++++++----- drivers/video/matrox/i2c-matroxfb.c | 20 +++++++++++++++----- include/linux/i2c.h | 2 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c index a0df63289b5..0cf96eb8a60 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 ca95f09d8b4..fcf9fadbf57 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 4baab7be58d..75ee5a12e54 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 7c36d5188d3..145797fe6a3 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 */ -- GitLab From 3401b2fff38fbb8b73ea6bcc69a8370ae5d2a7a0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: [PATCH 1897/2509] 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 --- drivers/i2c/busses/i2c-ali1535.c | 2 +- drivers/i2c/busses/i2c-ali1563.c | 2 +- drivers/i2c/busses/i2c-ali15x3.c | 2 +- drivers/i2c/busses/i2c-amd756.c | 2 +- drivers/i2c/busses/i2c-amd8111.c | 2 +- drivers/i2c/busses/i2c-cpm.c | 2 +- drivers/i2c/busses/i2c-elektor.c | 2 +- drivers/i2c/busses/i2c-gpio.c | 2 +- drivers/i2c/busses/i2c-i801.c | 2 +- drivers/i2c/busses/i2c-ibm_iic.c | 4 ++-- drivers/i2c/busses/i2c-iop3xx.c | 2 +- drivers/i2c/busses/i2c-isch.c | 2 +- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/i2c/busses/i2c-mv64xxx.c | 2 +- drivers/i2c/busses/i2c-nforce2.c | 2 +- drivers/i2c/busses/i2c-ocores.c | 2 +- drivers/i2c/busses/i2c-pasemi.c | 2 +- drivers/i2c/busses/i2c-piix4.c | 2 +- drivers/i2c/busses/i2c-pmcmsp.c | 2 +- drivers/i2c/busses/i2c-s3c2410.c | 2 +- drivers/i2c/busses/i2c-sibyte.c | 4 ++-- drivers/i2c/busses/i2c-sis5595.c | 2 +- drivers/i2c/busses/i2c-sis630.c | 2 +- drivers/i2c/busses/i2c-sis96x.c | 2 +- drivers/i2c/busses/i2c-stub.c | 2 +- drivers/i2c/busses/i2c-via.c | 2 +- drivers/i2c/busses/i2c-viapro.c | 2 +- drivers/i2c/busses/scx200_acb.c | 2 +- include/linux/i2c.h | 1 + 29 files changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 704436cdec8..8d1d90ab3a9 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 da5a382eee9..4b55ae19db8 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 7b029b147a8..e922c3950fc 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 f0baea62067..bd4f6380fab 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 a4f687915de..0e18fe84601 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 53af744a91c..8164de1f4d7 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 b7a9977b025..c251cf21a62 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 7c1b762aa68..79b455a1f09 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 213119211e5..9717ffe1292 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 85dbf34382e..6f7bfdec3c6 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 39884e79759..fc2714ac0c0 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 c9cd46b2269..8d648911a7f 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 a076129de7e..10b9342a36c 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 036e6a883e6..9e8118d2fe6 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 081fdf3393f..2654f20d3a6 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 f145692cbb7..51ca79bf648 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 1603c81e39d..adf0fbb902f 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 2bde47509e1..85d69f3e624 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 63b3e2c11cf..dcf2045b522 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 9e8c875437b..007390ad981 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 114634da6c6..ac8822e7a5b 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 328441bb547..f76944b384f 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 d7e6ff3e018..eb2b2181fed 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 cde8e588036..413e9e47772 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 e37ccd80f77..1b7b2af9403 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 61716f6b14d..6517f8a6d91 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 c611905df00..7957ce51589 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 61abe0f3325..ed794b145a1 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 145797fe6a3..839d0ea3dca 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 -- GitLab From d4653bf946a5856a17342cd47c47d10b16b1cc22 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: [PATCH 1898/2509] 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 --- drivers/i2c/chips/eeprom.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 7dee001e513..213a9f98dec 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) -- GitLab From 1b4dff9cd37d430bc76112396e92bb3552f37ccd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: [PATCH 1899/2509] 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 --- drivers/i2c/chips/eeprom.c | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 213a9f98dec..9a81252a721 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, " -- GitLab From e0457442fd522107204da14a2dc2cbbb5dcac5f6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: [PATCH 1900/2509] 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 --- drivers/i2c/i2c-core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e06067ebd20..d6cc58abf3f 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; -- GitLab From e6c3de6c146d2513332c581433caca6e5cae62bf Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: [PATCH 1901/2509] 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 --- drivers/i2c/busses/i2c-ibm_iic.c | 181 ------------------------------- 1 file changed, 181 deletions(-) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 6f7bfdec3c6..d8a19c11056 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); -- GitLab From d3dc685eb5ef64aa695dabb74f00440ec3ab6796 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: [PATCH 1902/2509] 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 --- drivers/i2c/busses/i2c-ibm_iic.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index d8a19c11056..070f078b5f5 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", }, {} }; -- GitLab From 47a9b1379a5ebc8b00ba8635d1d3885fc0d51739 Mon Sep 17 00:00:00 2001 From: Uli Luckas Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: [PATCH 1903/2509] 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 --- drivers/i2c/busses/i2c-pxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index eb69fbadc9c..78c0fc42bc7 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); -- GitLab From 8a56ce1033073657572bd993595a56498baa4800 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: [PATCH 1904/2509] 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 --- drivers/i2c/chips/Kconfig | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 2da2edfa68e..6326468d5f0 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" -- GitLab From 0573d11b2bbd0e4774f33f4c1959c1939c055e96 Mon Sep 17 00:00:00 2001 From: Eric Brower Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: [PATCH 1905/2509] 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 --- drivers/i2c/algos/i2c-algo-pcf.c | 48 +++++++++++++++++++++----------- include/linux/i2c-algo-pcf.h | 6 ++++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 8907b019167..1e328d19cd6 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 77afbb60fd1..74fb6f889a7 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 *); -- GitLab From e3e7fc3c401a5d53f0599a357b3cf65d6a4f52e3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: [PATCH 1906/2509] 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 --- drivers/i2c/busses/i2c-elektor.c | 2 -- include/linux/i2c-algo-pcf.h | 4 ---- 2 files changed, 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index c251cf21a62..7f38c01fb3a 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 74fb6f889a7..0177d280f73 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 -- GitLab From 90df2cb1c8822ef8d06a2b30627e7a810218b0dd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: [PATCH 1907/2509] 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 --- drivers/i2c/busses/i2c-i801.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9717ffe1292..965905fb5d5 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; -- GitLab From dcb5c9239de8d3ff1c663e75f0f1c75bcb21ee20 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: [PATCH 1908/2509] 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 --- drivers/i2c/busses/i2c-i801.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 965905fb5d5..614c9e4ffba 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"); -- GitLab From 2b73809d06649fe6c7f4294b051ca4934a34bb91 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: [PATCH 1909/2509] 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 --- drivers/i2c/busses/i2c-i801.c | 66 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 614c9e4ffba..73bd8552734 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) -- GitLab From cf898dc5e9dfd1487b28ca0176b68722f05d4d48 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: [PATCH 1910/2509] 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 --- drivers/i2c/busses/i2c-i801.c | 200 +++++++++++++++++----------------- 1 file changed, 102 insertions(+), 98 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 73bd8552734..46aa41f73fd 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) -- GitLab From 392a0408fdc4c9069c32a9a02b0088eae76c4618 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: [PATCH 1911/2509] 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 --- arch/mips/sibyte/swarm/Makefile | 1 + arch/mips/sibyte/swarm/swarm-i2c.c | 37 ++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-sibyte.c | 4 +++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 arch/mips/sibyte/swarm/swarm-i2c.c diff --git a/arch/mips/sibyte/swarm/Makefile b/arch/mips/sibyte/swarm/Makefile index 1775755a261..255d692bfa1 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 00000000000..4282ac9d01d --- /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 ac8822e7a5b..4ddefbf238e 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", }, }; -- GitLab From 2373c1801afd06d3a206376902b39a98458c9cfb Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: [PATCH 1912/2509] 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 --- drivers/i2c/busses/i2c-ocores.c | 42 +++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 51ca79bf648..e5193bf7548 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", }, -- GitLab From 54fb4a05af0a4b814e6716cfdf3fa97fc6be7a32 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: [PATCH 1913/2509] 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 --- drivers/i2c/busses/i2c-ali1535.c | 6 ++++++ drivers/i2c/busses/i2c-ali1563.c | 5 +++++ drivers/i2c/busses/i2c-ali15x3.c | 5 +++++ drivers/i2c/busses/i2c-amd756.c | 6 ++++++ drivers/i2c/busses/i2c-amd8111.c | 5 +++++ drivers/i2c/busses/i2c-i801.c | 5 +++++ drivers/i2c/busses/i2c-isch.c | 3 +++ drivers/i2c/busses/i2c-nforce2.c | 6 ++++++ drivers/i2c/busses/i2c-piix4.c | 4 ++++ drivers/i2c/busses/i2c-sis5595.c | 6 ++++++ drivers/i2c/busses/i2c-sis630.c | 6 ++++++ drivers/i2c/busses/i2c-sis96x.c | 5 +++++ drivers/i2c/busses/i2c-viapro.c | 5 +++++ 13 files changed, 67 insertions(+) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 8d1d90ab3a9..442d559b1aa 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 4b55ae19db8..fc3e5b02642 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 e922c3950fc..a030abd3b32 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 bd4f6380fab..26acc657e5c 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 0e18fe84601..3972208876b 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 46aa41f73fd..8d0bc4bfe15 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 8d648911a7f..b9c01aa9003 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 2654f20d3a6..3b19bc41a60 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 85d69f3e624..924e84a5348 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 f76944b384f..3c8e0e1bd24 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 eb2b2181fed..72c29a650b2 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 413e9e47772..848b37c97f7 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 7957ce51589..faef99560f2 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); -- GitLab From 954a99307f256f1badd751a2e128c09af235c317 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: [PATCH 1914/2509] i2c: Drop stray references to lm_sensors Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-ali1535.c | 2 -- drivers/i2c/busses/i2c-ali15x3.c | 2 -- drivers/i2c/busses/i2c-amd756.c | 3 --- drivers/i2c/busses/i2c-hydra.c | 3 --- drivers/i2c/busses/i2c-i801.c | 2 -- drivers/i2c/busses/i2c-piix4.c | 2 -- drivers/i2c/busses/i2c-sis5595.c | 2 -- drivers/i2c/busses/i2c-sis630.c | 3 --- drivers/i2c/busses/i2c-sis96x.c | 3 --- drivers/i2c/busses/i2c-via.c | 3 --- drivers/i2c/busses/i2c-viapro.c | 2 -- drivers/i2c/busses/i2c-voodoo3.c | 2 -- drivers/i2c/chips/eeprom.c | 8 +------- drivers/i2c/chips/pcf8574.c | 2 -- drivers/i2c/chips/pcf8591.c | 2 -- 15 files changed, 1 insertion(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 442d559b1aa..9cead9b9458 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 a030abd3b32..234fdde7d40 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 26acc657e5c..1ea39254dac 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 f9972f9651e..1098f21ace1 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 8d0bc4bfe15..dc7ea32b69a 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 924e84a5348..eaa9b387543 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 3c8e0e1bd24..dfc2d5eb6a6 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 72c29a650b2..e7c4b790da5 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 848b37c97f7..f1bba639664 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 6517f8a6d91..29cef0433f3 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 faef99560f2..862eb352a2d 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 88a3447e11e..1d4ae26ba73 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 9a81252a721..e22ec3b3aed 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 e5b31329b56..ad2f7901a8c 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 66c7c3bb942..d3a24524817 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 -- GitLab From f6a7110520037ba786f17b53790c6eb8a3d4ef55 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: [PATCH 1915/2509] 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 --- drivers/i2c/i2c-dev.c | 7 ------- include/linux/i2c-id.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index e96d9869678..50df53640c7 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 988e566d3ed..ef13b7c66df 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 */ /* -- GitLab From f09f71b24e77a2f2b4e5c98311c8804fc61ad8bc Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: [PATCH 1916/2509] 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 --- drivers/i2c/busses/i2c-au1550.c | 130 ++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 55 deletions(-) diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index cae9dc89d88..66a04c2c660 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 = { -- GitLab From e9ca9eb9d7fc7bf3dc3cec5ba7edb089c4625f7b Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 14 Jul 2008 22:38:35 +0200 Subject: [PATCH 1917/2509] 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 --- drivers/i2c/i2c-core.c | 3 ++- include/linux/i2c.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d6cc58abf3f..e45bb2838f4 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 839d0ea3dca..50cbab4b62b 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; -- GitLab From 2b7a5056a0a7ff17d5d2004c29c852a92a6bd632 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:35 +0200 Subject: [PATCH 1918/2509] 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 --- drivers/i2c/chips/Kconfig | 26 ++ drivers/i2c/chips/Makefile | 1 + drivers/i2c/chips/at24.c | 583 +++++++++++++++++++++++++++++++++++++ include/linux/i2c/at24.h | 28 ++ 4 files changed, 638 insertions(+) create mode 100644 drivers/i2c/chips/at24.c create mode 100644 include/linux/i2c/at24.h diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 6326468d5f0..50e0a465374 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 e47aca0ca5a..39e3e69ed12 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 00000000000..e764c94f3e3 --- /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 00000000000..f6edd522a92 --- /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 */ -- GitLab From b1204e6ec16468ebf89d9d818bfe425ca7adcdf3 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: [PATCH 1919/2509] 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 --- drivers/i2c/busses/i2c-ibm_iic.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 070f078b5f5..651f2f1ae5b 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)"); -- GitLab From f741f673298b03b92d46e30b0b6fd0e960423665 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: [PATCH 1920/2509] 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 --- drivers/i2c/chips/eeprom.c | 32 +++++++++++++++----------------- drivers/i2c/chips/max6875.c | 4 +--- drivers/i2c/chips/pca9539.c | 25 ++++++++++++------------- drivers/i2c/chips/pcf8574.c | 23 +++++++++++------------ drivers/i2c/chips/pcf8591.c | 31 +++++++++++++++---------------- 5 files changed, 54 insertions(+), 61 deletions(-) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index e22ec3b3aed..373ea8d8fe8 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 cf507b3f60f..5a0285d8b6f 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 f43c4e79b55..58ab7f26be2 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 ad2f7901a8c..1b3db2b3ada 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 d3a24524817..db735379f22 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: -- GitLab From 8508159e2f3b82bf109f0ec77bcbd8ff3f3a7e17 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: [PATCH 1921/2509] 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 --- drivers/i2c/i2c-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e45bb2838f4..5e249d75882 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); -- GitLab From 4735c98f8447acb1c8977e2b8024640f7bf36dd6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: [PATCH 1922/2509] 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 --- Documentation/i2c/writing-clients | 29 ++++ drivers/i2c/i2c-core.c | 223 ++++++++++++++++++++++++++++-- include/linux/i2c.h | 36 ++++- 3 files changed, 272 insertions(+), 16 deletions(-) diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 63722d3c9cd..6b61b3a2e90 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 5e249d75882..0a79f766101 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 50cbab4b62b..08be0d21864 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) -- GitLab From ce7231e92dac381f6e4f9cfdfdf9e0ea055223ad Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 13 May 2008 13:45:14 -0700 Subject: [PATCH 1923/2509] [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 --- fs/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/Kconfig b/fs/Kconfig index 2694648cbd1..9c07a4f49e6 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 -- GitLab From 8ddb7b004dfa1832a750e199df8bff4b75b73565 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 13 May 2008 13:45:15 -0700 Subject: [PATCH 1924/2509] [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 --- fs/ocfs2/dlmglue.c | 122 ++++++++++++++++++++++++++++++++++++++++++++- fs/ocfs2/ocfs2.h | 12 +++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 80e20d9f278..80537b769e4 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 31692379c17..1cb814be8ef 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 { -- GitLab From dd25e55ea133b14678cfaa9e205b082b24b26dbc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 28 May 2008 14:41:00 -0700 Subject: [PATCH 1925/2509] 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 --- fs/ocfs2/dlmglue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 80537b769e4..eae3d643a5e 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) -- GitLab From 7600c72b75bab374ad39b2a4799a0728579a8e2f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 9 Jun 2008 16:34:23 -0700 Subject: [PATCH 1926/2509] 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 --- fs/ocfs2/stack_user.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index c021280dd46..24e0b19c8b6 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) -- GitLab From 56753bd3b9220f6f2477eb1cf97f40c24e0a4c91 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 9 Jun 2008 11:24:41 -0700 Subject: [PATCH 1927/2509] 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 --- fs/ocfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 57e0d30cde9..e8514e8b6ce 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)); -- GitLab From 01af482037d32c215aab208a0b110ffe6fd782c0 Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Tue, 10 Jun 2008 14:24:48 +0800 Subject: [PATCH 1928/2509] 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 --- fs/ocfs2/super.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index df63ba20ae9..ccecfe5094f 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. */ -- GitLab From 461c6a30eca6f25add1dadb9fd8a1d8e89a6e627 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 19 May 2008 16:23:37 -0700 Subject: [PATCH 1929/2509] 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 --- fs/ocfs2/cluster/netdebug.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 7bf3c0ea7bd..d8bfa0eb41b 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) { -- GitLab From e407e39783a7206d20b3e9961aedf272de966e31 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 22:35:39 -0700 Subject: [PATCH 1930/2509] 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 --- fs/ocfs2/journal.c | 2 +- fs/ocfs2/localalloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 9698338adc3..a8c19cb3cfd 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 be774bdc8b3..28e492e4ec8 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 " -- GitLab From fe9f387740ac7cb3b7c2fffa76807e997e6c6292 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 22:39:18 -0700 Subject: [PATCH 1931/2509] 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 --- fs/ocfs2/ocfs2_fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 52c42666515..3f194517762 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, -- GitLab From 6f61076406251626be39651d114fac412b1e0c39 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:00:58 +0200 Subject: [PATCH 1932/2509] 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 --- fs/configfs/configfs_internal.h | 3 +++ fs/configfs/dir.c | 28 +++++++++++++++++++++++++++- fs/configfs/inode.c | 2 ++ fs/configfs/symlink.c | 2 ++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index cca98609aa7..5a33b58e66d 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 a48dc7dd876..2619f485bc3 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 b9a1d810346..4803ccc9448 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 2a731ef5f30..676c84c416d 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); -- GitLab From 5301a77da2da1e4c22573e0e8d394a653b8ad9f9 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:00:59 +0200 Subject: [PATCH 1933/2509] 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 --- fs/configfs/dir.c | 5 +++-- fs/configfs/symlink.c | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 2619f485bc3..a08e5c2f25e 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 676c84c416d..faeb4417a10 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); -- GitLab From 107ed40bd070df5e4a0a012042c45c40963dc574 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:00 +0200 Subject: [PATCH 1934/2509] 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 --- fs/configfs/dir.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index a08e5c2f25e..918a332babf 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; } -- GitLab From b3e76af87441fc36eef3516d73ab2314e7b2d911 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:01 +0200 Subject: [PATCH 1935/2509] 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 --- fs/configfs/dir.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 918a332babf..d5b5985716b 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); -- GitLab From 6d8344baee99402de58b5fa5dfea197242955c15 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:02 +0200 Subject: [PATCH 1936/2509] 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 --- fs/configfs/configfs_internal.h | 1 + fs/configfs/dir.c | 53 ++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 5a33b58e66d..da015c12e3e 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 d5b5985716b..614e382a604 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); -- GitLab From 11c3b79218390a139f2d474ee1e983a672d5839a Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 14:00:18 -0700 Subject: [PATCH 1937/2509] 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 --- .../filesystems/configfs/configfs.txt | 10 +++-- .../filesystems/configfs/configfs_example.c | 14 +++--- drivers/net/netconsole.c | 10 +++-- fs/configfs/dir.c | 13 +++--- fs/dlm/config.c | 45 ++++++++++++------- fs/ocfs2/cluster/heartbeat.c | 17 ++++--- fs/ocfs2/cluster/nodemanager.c | 45 ++++++++++++------- include/linux/configfs.h | 4 +- 8 files changed, 94 insertions(+), 64 deletions(-) diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt index 44c97e6accb..15838d706ea 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 25151fd5c2c..0b422acd470 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 665341e4305..387a1339501 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 614e382a604..0e64312a084 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 eac23bd288b..492d8caaaf2 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 f02ccb34604..443d108211a 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 cfdb08b484e..b364b7052e4 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 3ae65b1bf90..0488f937634 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); -- GitLab From e75206517504461778c283b942440ef312e437d5 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Thu, 12 Jun 2008 17:26:47 +0200 Subject: [PATCH 1938/2509] 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 --- fs/configfs/symlink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index faeb4417a10..0004d18c40a 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); -- GitLab From a41eebab7537890409ea9dfe0fcda9b5fbdb090d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 14 Jul 2008 16:41:12 -0400 Subject: [PATCH 1939/2509] 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 --- Documentation/ftrace.txt | 134 +++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index 13e4bf054c3..77d3faa1a61 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 -- GitLab From beef3129b3afb74817acff72fda4a9d951e3973e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 11 Jul 2008 15:21:17 -0600 Subject: [PATCH 1940/2509] 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 --- arch/x86/pci/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index d19fd07bafd..86aff81a082 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); -- GitLab From c157dfa3e4aea5775389f2f4d53c040bc8813af1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 13 Jul 2008 22:45:06 +0200 Subject: [PATCH 1941/2509] 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 --- drivers/pci/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e632a58ba5d..ace518116cc 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) -- GitLab From c300bd2fb583afb6d68804afd38bc90b31310d95 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 10 Jul 2008 02:16:44 +0200 Subject: [PATCH 1942/2509] 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 --- drivers/pci/pci.c | 1 + include/linux/pm_wakeup.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ace518116cc..44a46c92b72 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 3af0c8d05cd..0aae7776185 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; -- GitLab From 04a33e406a062cd1bb55014ee17a3558109a2d74 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 23 Jun 2008 11:36:23 +0100 Subject: [PATCH 1943/2509] cpia2: use request_firmware() Thanks for Jaswinder Singh for converting the firmware blob itself to ihex. Signed-off-by: David Woodhouse --- drivers/media/video/cpia2/cpia2_core.c | 46 ++++- drivers/media/video/cpia2/cpia2patch.h | 233 ------------------------- firmware/Makefile | 1 + firmware/WHENCE | 13 ++ firmware/cpia2/stv0672_vp4.bin.ihex | 73 ++++++++ 5 files changed, 124 insertions(+), 242 deletions(-) delete mode 100644 drivers/media/video/cpia2/cpia2patch.h create mode 100644 firmware/cpia2/stv0672_vp4.bin.ihex diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index c8b9fdb700f..f2e8b1c82c6 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 7f085fbe76f..00000000000 --- 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 2f81089dfd2..8d5465fefd0 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 6c7b0b44712..d8f6199d087 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 00000000000..bd0b9cf6564 --- /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. -- GitLab From c466774636b3cc43c2c304b44e52974d9d53f3e0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 23 Jun 2008 11:41:04 +0100 Subject: [PATCH 1944/2509] dabusb: use request_firmware() Signed-off-by: David Woodhouse --- drivers/media/video/dabfirmware.h | 1415 ---------------------------- drivers/media/video/dabusb.c | 44 +- firmware/Makefile | 3 + firmware/WHENCE | 16 + firmware/dabusb/bitstream.bin.ihex | 761 +++++++++++++++ firmware/dabusb/firmware.HEX | 649 +++++++++++++ 6 files changed, 1461 insertions(+), 1427 deletions(-) delete mode 100644 drivers/media/video/dabfirmware.h create mode 100644 firmware/dabusb/bitstream.bin.ihex create mode 100644 firmware/dabusb/firmware.HEX diff --git a/drivers/media/video/dabfirmware.h b/drivers/media/video/dabfirmware.h deleted file mode 100644 index cbd92635993..00000000000 --- 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 8d1f8ee2a53..48f4b92a8f8 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 8d5465fefd0..331d10cf651 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 d8f6199d087..87845657292 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 00000000000..5021a4b1e63 --- /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 00000000000..7c258df2b0a --- /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. -- GitLab From fb54be8755d386008bfadb7fc8ff89451fa3a9c9 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Fri, 27 Jun 2008 19:50:40 +0530 Subject: [PATCH 1945/2509] 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 --- drivers/media/video/usbvideo/vicam.c | 317 ++------------------------- firmware/Makefile | 1 + firmware/WHENCE | 10 + firmware/vicam/firmware.H16 | 7 + 4 files changed, 39 insertions(+), 296 deletions(-) create mode 100644 firmware/vicam/firmware.H16 diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 17f542dfb36..40d053e0d5b 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 331d10cf651..5ed36ae1a41 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 87845657292..b14b86c8fb5 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 00000000000..cac0cba68cc --- /dev/null +++ b/firmware/vicam/firmware.H16 @@ -0,0 +1,7 @@ +:0026000000B6C31F000264E767FDFF0EC0E709DE008E00C0094003C01744034BAFC00700004BAF97CF00001D +:000A000000B6C30300036418000000FB +:0008000000B6C301000664000014 +:0696000000B6C38F060264E707000008C0E70700003EC0E7075401AA00E707C805B600E7074201D200E7077C001600E70756001800E707060092C0E70700001EC0E707FFFF22C0E707040024C0E707EC2728C0E70716018E00E78701000EC097CFD70900C0E777010092C009C1E709FE052401E70904062601E707070092C0E70500C0C0DF97CF170057001702D70900C0E777010092C00AC1E757FFFFFA050DC0E7570000FA050FC09FAFC600E70500C0C805C105C005C0DF97CF27DAFA05EF0701000B0673CF9FAF78019FAF1A036ECFE709FC052401E70902062601E707070092C0E709FC05FE05E70902060406E7090006FC05E709FE05000627DAFA05E7570100FA0502CA04C097CF9FAF660597CFE70740000206C809FC059FAFDA0297CFCF170200EF57810009069FA0B601EF57800009069FA04002EF5701000B069FA04603E70701000AC046AF47AF9FAF4002E7072E000AC0EF878000090697CF000E0100C05751009FC09E02C057500020C0C057550012C0C05756009FC072029FCFD602C10B080601D06F900806C0070800C10B08069FAF280597CF2F0E02000806C0070800C10B08069FAF28059FCFD6022F0E02000906EF87800009069FCFD602EF677FFF0906E767FFFD22C0E767EFFF24C0E787100028C09FAFB805E787E02124C09FAFA805E787080024C0E767DFFF24C0C8070A00C0070000C10701009FAF28059FAFB805C0079E009FAF4405E767FFFE24C0C00920C0E787000124C0C07700020FC1E767F7FF24C0E767F7FF24C0E787080024C008DA5EC1EF078000090697CFEF0701000A0697CFEF0700000B06EF0700000A06EF677FFF0906EF0700000D06E767EFFF28C0E76717D824C0E70700001EC0E707FFFF22C097CFC8070E069FAFDA02E7070000F205E7071000F605E7070E06F405E707D602F805C807F205C107008050AF97CF2F0C020007062F0C04000606E7070000F205E7071000F605E707E205F405E707CE02F805C807F205C107008051AF97CF9FAF66049FAF1A0359AF97CFC0070E00C10B0C0641D19FAF2805C0073C009FAF44056800C0073B009FAF44056F000C066800E0070401E80B0A06E8070000E0070002E007EC01E007FCFF97CFE707FFFFFA05EF0700000B06E7070E062401E7070E06FE05E70740002601E70740000406E707070092C097CFEF0702000B069FAF7801EF77800007069FC01404EF770100070637C0EF7701000D060FC1EF0701000D06C0070200C10730009FAF2805C0070100C10702009FAF2805C807FF4F9FAFA805C00738009FAF4405C177030002C108DA75C1C17701000AC1C0070100C10702009FAF2805EF07010006062CCFC0070100C10704009FAF2805EF070000060622CFEF0700000D06EF57010006061BC0C0070100C10701009FAF2805C0070200C10730009FAF2805C807FF4F9FAFA805C00738009FAF4405C1670300C157030002C008DA73C1C0070200C1071200EF570000060602C0C10723009FAF2805C0071400C10BEA059FAF2805C0073E009FAF0A05E709E405FA0527D8FA05E7070E06FC05E7074E060006E707400002069FAF66059FAFC60097CFC10BE20541D001D2C11723009FAFDC04C0070400C10BE3059FAF2805C0070600C109E6059FAF2805C0070700C109E605C1D19FAF2805C0070B00C109E8059FAF2805C0070C00C109E805C1D19FAF2805C0070D00C10709009FAF2805C0070300C10732009FAF2805C0070F00C10700009FAF280597CFE767FFD924C0C8070A004000C0670002278024C0E787000424C0E767FFF924C001D208DA72C1E787002024C097CF27001EC0E787FF0022C0E7677FFF24C0E787800024C0E787800024C097CF9FAF0A0567001EC0E767BFFF24C0E787400024C0E787400024C097CF9FAF0A05E76700FF22C0E767FFFE24C0E767FFFE24C0C10920C0E787000124C097CFC0074000C809FC05E76700FF22C0E767FFFE24C0E767BFFF24C0E767BFFF24C000DAE80920C0E787400024C0E787400024C000DAE80920C06DC1E787000124C097CFE707320012C0E777008012C07CC097CFE707204E12C0E777008012C07CC097CF0902190001010080960904000001000000000705810240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1 +:0136000000B6C32F0103640E0014001A00200026004A0064006A0092009A00A000B200B800BE00C200C800CE00DC00DA00E200E000E800E600EE00EC00F200F80002010A010E0112011E01220128012C0132013601440150015E01720176017A01800188018C0194019C01A001A401AA01B001B401BA01D001DA01F601FA01020234023C0244024A0250025602740278027E0284028A02880290028E029402A202A802AE02B402BA02B802C002BE02C402D002D402E002E602EE02F802FC0206031E032403280330032E033C034A034E03540358035E0366036E037A0386038E039603B203B803C603CC03D403DA03E803F403FC03040420042A04320436043E044404420448044E044C04540452045A045E046204680474047C04800488048C0494049A04A204A604AE04B404C004CC04D8042A0546056C0500005E +:0008000000B6C301000664000014 +:0000000001FF -- GitLab From 5b9ea9322605da09d6f7119f03f71cc52b044911 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Thu, 3 Jul 2008 17:00:23 +0530 Subject: [PATCH 1946/2509] edgeport: use request_firmware() Version number provided in first HEX record. Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse --- drivers/usb/serial/io_edgeport.c | 183 +++-- drivers/usb/serial/io_fw_boot.h | 556 -------------- drivers/usb/serial/io_fw_boot2.h | 546 ------------- drivers/usb/serial/io_fw_down.h | 1229 ------------------------------ drivers/usb/serial/io_fw_down2.h | 1133 --------------------------- firmware/Makefile | 2 + firmware/WHENCE | 18 + firmware/edgeport/boot.H16 | 29 + firmware/edgeport/boot2.H16 | 28 + firmware/edgeport/down.H16 | 29 + firmware/edgeport/down2.H16 | 29 + 11 files changed, 225 insertions(+), 3557 deletions(-) delete mode 100644 drivers/usb/serial/io_fw_boot.h delete mode 100644 drivers/usb/serial/io_fw_boot2.h delete mode 100644 drivers/usb/serial/io_fw_down.h delete mode 100644 drivers/usb/serial/io_fw_down2.h create mode 100644 firmware/edgeport/boot.H16 create mode 100644 firmware/edgeport/boot2.H16 create mode 100644 firmware/edgeport/down.H16 create mode 100644 firmware/edgeport/down2.H16 diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 06b52f4098f..2fd449bcfa3 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 099fafaf52b..00000000000 --- 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 e3463de99de..00000000000 --- 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 5a61d809a46..00000000000 --- 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 067277efd3b..00000000000 --- 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 5ed36ae1a41..be3a9e97d56 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 b14b86c8fb5..8eada2dbd56 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 00000000000..4bf8e91a975 --- /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 00000000000..8b14295e1f3 --- /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 00000000000..7e36fe1f218 --- /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 00000000000..2f4b4ff3ab7 --- /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. +//************************************************************** -- GitLab From d12b219a228efe92f0778ed3af21305e65fbb052 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Fri, 4 Jul 2008 23:06:09 +0530 Subject: [PATCH 1947/2509] 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 --- drivers/usb/serial/io_fw_down3.h | 847 ------------------------------- drivers/usb/serial/io_ti.c | 73 ++- firmware/Makefile | 1 + firmware/WHENCE | 16 + firmware/edgeport/down3.bin.ihex | 815 +++++++++++++++++++++++++++++ 5 files changed, 879 insertions(+), 873 deletions(-) delete mode 100644 drivers/usb/serial/io_fw_down3.h create mode 100644 firmware/edgeport/down3.bin.ihex diff --git a/drivers/usb/serial/io_fw_down3.h b/drivers/usb/serial/io_fw_down3.h deleted file mode 100644 index 4496b068c50..00000000000 --- 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 05e4fa73073..61daea3f7b2 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 be3a9e97d56..a162b2928fb 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 8eada2dbd56..79e62e2fea5 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 00000000000..7935e520878 --- /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. +//************************************************************** -- GitLab From 7f127d5ed0da66053482a3e18014c439da3c41d1 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Sat, 5 Jul 2008 15:28:30 +0530 Subject: [PATCH 1948/2509] dsp56k: use request_firmware Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse --- drivers/char/dsp56k.c | 84 ++++++++++--------------- firmware/Makefile | 1 + firmware/WHENCE | 12 ++++ firmware/dsp56k/bootstrap.asm | 98 ++++++++++++++++++++++++++++++ firmware/dsp56k/bootstrap.bin.ihex | 26 ++++++++ 5 files changed, 170 insertions(+), 51 deletions(-) create mode 100644 firmware/dsp56k/bootstrap.asm create mode 100644 firmware/dsp56k/bootstrap.bin.ihex diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index a69c6528326..d716c78f0ff 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 a162b2928fb..782c499a373 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 79e62e2fea5..5c1dc159639 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 00000000000..10d891929cd --- /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: [PATCH 1949/2509] firmware: convert sb16_csp driver to use firmware loader exclusively Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse --- firmware/Makefile | 4 + firmware/WHENCE | 18 + firmware/sb16/alaw_main.csp.ihex | 87 ++ firmware/sb16/ima_adpcm_capture.csp.ihex | 121 +++ firmware/sb16/ima_adpcm_init.csp.ihex | 70 ++ firmware/sb16/ima_adpcm_playback.csp.ihex | 122 +++ firmware/sb16/mulaw_main.csp.ihex | 84 ++ sound/isa/Kconfig | 9 - sound/isa/sb/sb16_csp.c | 22 - sound/isa/sb/sb16_csp_codecs.h | 949 ---------------------- 10 files changed, 506 insertions(+), 980 deletions(-) create mode 100644 firmware/sb16/alaw_main.csp.ihex create mode 100644 firmware/sb16/ima_adpcm_capture.csp.ihex create mode 100644 firmware/sb16/ima_adpcm_init.csp.ihex create mode 100644 firmware/sb16/ima_adpcm_playback.csp.ihex create mode 100644 firmware/sb16/mulaw_main.csp.ihex delete mode 100644 sound/isa/sb/sb16_csp_codecs.h diff --git a/firmware/Makefile b/firmware/Makefile index 782c499a373..10028ace2de 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 5c1dc159639..66c51b275e9 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 00000000000..04502707c42 --- /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 00000000000..9a50a58564a --- /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 00000000000..a899a9e743f --- /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 00000000000..f09f18cf35e --- /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 00000000000..b64b565f229 --- /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 2639a6ab8f2..1ff9f631084 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 f3fd7b4f466..35f3d7b1653 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 f0e8b0dcb57..00000000000 --- 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 -}; -- GitLab From 116a9fb3ed98c19d1ee0c6c55971f5b753949393 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jul 2008 15:03:25 -0700 Subject: [PATCH 1950/2509] 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 --- arch/x86/Kconfig.debug | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 5236621350b..ae36bfa814e 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 -- GitLab From 50515af207d410c9f228380e529c56f43c3de0bd Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 14 Jul 2008 17:50:24 -0700 Subject: [PATCH 1951/2509] 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 --- firmware/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/Makefile b/firmware/Makefile index 10028ace2de..809a52624bd 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. -- GitLab From b3fcaaa8a6359e9ed623ed4c1d2d48c79eed4648 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 14 Jul 2008 19:25:57 +1000 Subject: [PATCH 1952/2509] 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 --- include/asm-powerpc/Kbuild | 1 - include/asm-powerpc/mman.h | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild index 34a0a8db010..04ce8f8a2ee 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 f8a32e20ba0..9209f755763 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 */ -- GitLab From fe9e8d53772b5ea9ccf8ea4e8f0f009a6885eb70 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Tue, 8 Jul 2008 15:45:11 +1000 Subject: [PATCH 1953/2509] 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 --- arch/powerpc/configs/pseries_defconfig | 1 + drivers/char/Kconfig | 8 + drivers/char/Makefile | 1 + drivers/char/bsr.c | 312 +++++++++++++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 drivers/char/bsr.c diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index adaa05fb047..fe6ffa683d7 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 2d854bb9373..650e6b44ce6 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 4c1c584e9eb..d38ac503076 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 00000000000..b650b4e48e5 --- /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 "); -- GitLab From 0f47331475201c7785454030a9976c8ac902a35d Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Thu, 10 Jul 2008 01:06:57 +1000 Subject: [PATCH 1954/2509] 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 --- arch/powerpc/kernel/cputable.c | 6 ++++-- include/asm-powerpc/cputable.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 72adb19a204..f7f3c215d06 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 4fd76898975..2a3e9075a5a 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 -- GitLab From 443dcac4d89622cbfc61f53523007979879d6f8e Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Thu, 10 Jul 2008 01:28:07 +1000 Subject: [PATCH 1955/2509] 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 --- arch/powerpc/platforms/cell/beat_htab.c | 4 ++-- arch/powerpc/platforms/pseries/lpar.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c index 81467ff055c..2e67bd840e0 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 38b5927b362..52a80e5840e 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); -- GitLab From 01f4b8b8b8db09b88be7df7e51192e4e678b69d3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 11 Jul 2008 00:08:18 +1000 Subject: [PATCH 1956/2509] 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 --- arch/powerpc/Kconfig | 3 +++ arch/powerpc/kernel/stacktrace.c | 37 +++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index aaf99892d1b..5e2185432ad 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 96294403843..6a4fb003fa5 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); -- GitLab From 7c29217096d83f657e6ee70479af09b46f4275f6 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jul 2008 16:29:12 +1000 Subject: [PATCH 1957/2509] 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 --- arch/powerpc/kernel/misc_64.S | 8 ++++---- arch/powerpc/kernel/process.c | 10 +++++++++- arch/powerpc/kernel/signal_32.c | 2 +- arch/powerpc/kernel/signal_64.c | 2 +- include/asm-powerpc/system.h | 1 + 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 31b9026cf1e..4dd70cf7bb4 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 0a4eb081159..219f3634115 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 6f6810db0a7..3e80aa32b8b 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 5f9d2ef2e24..65ad925c3a8 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 0c12c66733f..e6e25e2364e 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 *); -- GitLab From cd6f37be7fdc9fea407379745350f6630b9d3cdd Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jul 2008 16:31:09 +1000 Subject: [PATCH 1958/2509] 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 --- arch/powerpc/kernel/align.c | 58 ++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index f22b5d0a4a9..367129789cc 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 */ -- GitLab From b6f6b98a4e91fcf31db7de54c3aa86252fc6fb5f Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Sat, 12 Jul 2008 09:00:26 +1000 Subject: [PATCH 1959/2509] 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 --- arch/powerpc/kernel/head_64.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index ecced1eb03a..cc8fb474d52 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) -- GitLab From 004ea683d96ff51131789e78a3de7dafcdbf912d Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Wed, 9 Jul 2008 01:03:06 +1000 Subject: [PATCH 1960/2509] 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 --- drivers/net/ibm_newemac/rgmii.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index e32da3de269..1d5379de690 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: -- GitLab From ad1f8bf073e1c1996bb37b669352e3d7b1eb2b1f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 14 Jul 2008 18:13:10 -0700 Subject: [PATCH 1961/2509] 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 --- firmware/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 809a52624bd..e4f2fb3d191 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 -- GitLab From 4d3702b62e004172f44870763cf56793d8de0cbf Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 18:11:23 -0700 Subject: [PATCH 1962/2509] 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 --- include/asm-x86/dwarf2.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index 0bfe250894f..fd4a6a0393a 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 -- GitLab From 7ff86b0317bc40c665aab62f3b7669713ade07c5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 16 Jul 2008 02:20:11 +0200 Subject: [PATCH 1963/2509] 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 --- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5e2185432ad..06b72771ae2 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 -- GitLab From 585583d95c5660973bc0cf64add517b040acd8a4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 14 Jul 2008 08:08:45 -0500 Subject: [PATCH 1964/2509] 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 --- include/asm-powerpc/pgtable-ppc32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index 11eede4a290..73015f0139d 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 -- GitLab From 242e3df80b8d25ed681c278512df0993725f25dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 15 Jul 2008 15:48:05 +1000 Subject: [PATCH 1965/2509] 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 --- drivers/gpu/drm/drm_memory.c | 5 +++++ drivers/gpu/drm/radeon/radeon_cp.c | 2 +- include/drm/drmP.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index 845081b44f6..0177012845c 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 e53158f0ecb..f0de81a5689 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 0764b662b33..1c1b13e2922 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, -- GitLab From 9527056630b68c94b94b94cd58c6cbb65e611fd1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 17:58:44 +0300 Subject: [PATCH 1966/2509] MAINTAINERS: add UBIFS section Signed-off-by: Artem Bityutskiy --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 56a2f678019..3882f9cf602 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 -- GitLab From e56a99d5a42dcb91e622ae7a0289d8fb2ddabffb Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:34 +0300 Subject: [PATCH 1967/2509] UBIFS: add brief documentation Signed-off-by: Artem Bityutskiy Signed-off-by: Adrian Hunter --- Documentation/filesystems/ubifs.txt | 164 ++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Documentation/filesystems/ubifs.txt diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt new file mode 100644 index 00000000000..540e9e7f59c --- /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 -- GitLab From 969a60f9db3f879f95bd37026a3c3bf02cc2568f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: [PATCH 1968/2509] 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 --- drivers/infiniband/ulp/srp/ib_srp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 435145709dd..81cc59ca559 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 " -- GitLab From 929555a2baed9b0b050d03532655bfd721a43c44 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: [PATCH 1969/2509] 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 --- drivers/infiniband/hw/nes/nes_cm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 9a4b40fae40..6aa531d5276 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; -- GitLab From a9474917099e007c0f51d5474394b5890111614f Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: [PATCH 1970/2509] 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 --- drivers/infiniband/core/addr.c | 41 ++++++++++++++++------------ drivers/infiniband/core/cma.c | 42 +++++++++++++++------------- include/rdma/ib_addr.h | 42 +++++++++++++++------------- include/rdma/rdma_cm.h | 42 +++++++++++++++------------- include/rdma/rdma_cm_ib.h | 50 ++++++++++++++++++---------------- 5 files changed, 119 insertions(+), 98 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 781ea595037..e4eb8be3bb0 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 671f1373805..e5bd6172a1f 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 c36750ff6ae..b42bdd00041 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 010f876f41d..d8f9a95541c 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 950424b38f1..2389c3b4540 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) -- GitLab From 164ba0893c27a216557396320b6063fdac040392 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: [PATCH 1971/2509] 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 --- drivers/infiniband/core/sa_query.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index cf474ec2707..78ea8157d62 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); -- GitLab From 9670e553915e67fb68f13258644342c68dc26b84 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: [PATCH 1972/2509] 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 --- drivers/infiniband/hw/mlx4/qp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a80df22deae..4b0ac5d68c4 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); } -- GitLab From fd91b1bf1bb6fb443cb8c7600c7314f093b31f40 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: [PATCH 1973/2509] IB/ipath: Simplify code using ARRAY_SIZE() macro Signed-off-by: Robert P. J. Day Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ipath/ipath_iba7220.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c index 8eee7830f04..fb70712ac85 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++) { -- GitLab From 4deccd6d95f1f1536dad3c842e39c1ace577329d Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: [PATCH 1974/2509] 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 --- include/rdma/ib_cache.h | 2 -- include/rdma/ib_cm.h | 2 -- include/rdma/ib_fmr_pool.h | 4 +--- include/rdma/ib_mad.h | 17 +++++++---------- include/rdma/ib_pack.h | 2 -- include/rdma/ib_sa.h | 2 -- include/rdma/ib_smi.h | 4 +--- include/rdma/ib_user_cm.h | 2 -- include/rdma/ib_user_mad.h | 2 -- include/rdma/ib_user_verbs.h | 2 -- include/rdma/ib_verbs.h | 6 ++---- include/rdma/iw_cm.h | 2 +- include/rdma/rdma_cm.h | 10 +++++----- 13 files changed, 17 insertions(+), 40 deletions(-) diff --git a/include/rdma/ib_cache.h b/include/rdma/ib_cache.h index f179d233ffc..00a2b8ec327 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 a627c8682d2..ec7c6d99ed3 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 00dadbf94e1..f62b842e659 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 7228c056b9e..5f6c40fffcf 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 f926020d633..d7fc45c4eba 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 942692b0b92..3841c1aff69 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 f29af135ba8..aaca0878668 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 37650afb982..bd3d380781e 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 29d2c7205a9..d6fce1cbdb9 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 8d65bf0a625..885254f20bb 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 31d30b1852e..5f5621bf70b 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 aeefa9b740d..cbb822e8d79 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 d8f9a95541c..22bb2e7bab1 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 { -- GitLab From f3781d2e89f12dd5afa046dc56032af6e39bd116 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: [PATCH 1975/2509] RDMA: Remove subversion $Id tags They don't get updated by git and so they're worse than useless. Signed-off-by: Roland Dreier --- drivers/infiniband/core/agent.h | 2 -- drivers/infiniband/core/cache.c | 2 -- drivers/infiniband/core/cm.c | 2 -- drivers/infiniband/core/core_priv.h | 2 -- drivers/infiniband/core/device.c | 2 -- drivers/infiniband/core/fmr_pool.c | 2 -- drivers/infiniband/core/mad_priv.h | 2 -- drivers/infiniband/core/mad_rmpp.c | 2 -- drivers/infiniband/core/mad_rmpp.h | 2 -- drivers/infiniband/core/packer.c | 2 -- drivers/infiniband/core/sa_query.c | 2 -- drivers/infiniband/core/sysfs.c | 2 -- drivers/infiniband/core/ucm.c | 2 -- drivers/infiniband/core/ud_header.c | 2 -- drivers/infiniband/core/umem.c | 2 -- drivers/infiniband/core/user_mad.c | 2 -- drivers/infiniband/core/uverbs.h | 2 -- drivers/infiniband/core/uverbs_cmd.c | 2 -- drivers/infiniband/core/uverbs_main.c | 2 -- drivers/infiniband/core/verbs.c | 2 -- drivers/infiniband/hw/mthca/mthca_allocator.c | 2 -- drivers/infiniband/hw/mthca/mthca_av.c | 2 -- drivers/infiniband/hw/mthca/mthca_catas.c | 2 -- drivers/infiniband/hw/mthca/mthca_cmd.c | 2 -- drivers/infiniband/hw/mthca/mthca_cmd.h | 2 -- drivers/infiniband/hw/mthca/mthca_config_reg.h | 2 -- drivers/infiniband/hw/mthca/mthca_cq.c | 2 -- drivers/infiniband/hw/mthca/mthca_dev.h | 2 -- drivers/infiniband/hw/mthca/mthca_doorbell.h | 2 -- drivers/infiniband/hw/mthca/mthca_eq.c | 2 -- drivers/infiniband/hw/mthca/mthca_mad.c | 2 -- drivers/infiniband/hw/mthca/mthca_main.c | 2 -- drivers/infiniband/hw/mthca/mthca_mcg.c | 2 -- drivers/infiniband/hw/mthca/mthca_memfree.c | 2 -- drivers/infiniband/hw/mthca/mthca_memfree.h | 2 -- drivers/infiniband/hw/mthca/mthca_mr.c | 2 -- drivers/infiniband/hw/mthca/mthca_pd.c | 2 -- drivers/infiniband/hw/mthca/mthca_profile.c | 2 -- drivers/infiniband/hw/mthca/mthca_profile.h | 2 -- drivers/infiniband/hw/mthca/mthca_provider.c | 2 -- drivers/infiniband/hw/mthca/mthca_provider.h | 2 -- drivers/infiniband/hw/mthca/mthca_qp.c | 2 -- drivers/infiniband/hw/mthca/mthca_reset.c | 2 -- drivers/infiniband/hw/mthca/mthca_srq.c | 2 -- drivers/infiniband/hw/mthca/mthca_uar.c | 2 -- drivers/infiniband/hw/mthca/mthca_user.h | 1 - drivers/infiniband/hw/mthca/mthca_wqe.h | 2 -- drivers/infiniband/ulp/ipoib/ipoib.h | 2 -- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_main.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 2 -- drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 2 -- drivers/infiniband/ulp/iser/iscsi_iser.c | 3 --- drivers/infiniband/ulp/iser/iscsi_iser.h | 2 -- drivers/infiniband/ulp/iser/iser_initiator.c | 2 -- drivers/infiniband/ulp/iser/iser_memory.c | 2 -- drivers/infiniband/ulp/iser/iser_verbs.c | 2 -- drivers/infiniband/ulp/srp/ib_srp.c | 2 -- drivers/infiniband/ulp/srp/ib_srp.h | 2 -- 62 files changed, 124 deletions(-) diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index fb9ed1489f9..6669287009c 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 e85f7013de5..68883565b72 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 a47fe64e5c3..55738eead3b 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 7ad47a4b166..05ac36e6acd 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 5ac5ffee05c..7913b804311 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 1286dc1b98b..4507043d24c 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 8b75010016e..05ce331733b 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 a5e2a310f31..d0ef7d61c03 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 f0616fd2249..3d336bff114 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 c972d723576..019bd4b0863 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 78ea8157d62..1341de793e5 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 95756551cf7..36a0ef97c6a 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 b25675faaaf..9494005d1c9 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 997c07db6d8..8ec7876bedc 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 a1768dbb072..6f7c096abf1 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 208c7f34323..268a2d23b7c 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 376a57ce1b4..b3ea9587dc8 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 2c3bff5fe86..112b37cd689 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 0f34858e31e..aeee856c406 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 05042089de6..9f399d3a42b 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 a7630670961..c5ccc2daab6 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 4b111a852ff..32f6c631545 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 e948158a28d..40573e48439 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 54d230ee7d6..c33e1c53c79 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 8928ca4a932..6efd3265f24 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 afa56bfaab2..75671f75cac 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 20401d2ba6b..f788fce71ac 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 7bc32f8e377..2997d8d564e 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 b374dc395be..14f51ef97d7 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 8bde7f98e58..4e36aa7cb3d 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 8b7e83e6e88..640449582ab 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 200cf13fc9b..fb9f91b60f3 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 a8ad072be07..3f5f9487920 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 d5862e5d99a..1f7d1a29d2a 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 a1ab06847b7..da9b8f9b884 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 820205dec56..8489b1e81c0 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 c1e950764bd..266f14e4740 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 605a8d57fac..d168c254061 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 e76cb62d8e3..62b009cc873 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 be34f99ca62..87ad889e367 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 934bf954403..c621f8794b8 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 09dc3614cf2..3b1c5baf13b 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 91934f2d9db..acb6817f606 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 a5ffff6e102..4fabe62aab8 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 8b728486410..ca5900c96fc 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 e1262c942db..5fe56e81073 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 b3551a8dea1..341a5ae881c 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 ca126fc2b85..0dcbab3203c 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 97e67d36378..91c95929991 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 8b882bbd1d0..961c585da21 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 f429bce24c2..eca8518d79a 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 2442090ac8d..f217b1edd0a 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 3f663fb852c..4a6538b9301 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 8766d29ce3b..810790ae753 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 1cdb5cfb0ff..b08eb56196d 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 aeb58cae9a3..356fac6d105 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 a8c1b300e34..0e10703cf59 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 08dc81c46f4..31ad498bdc5 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 cac50c4dc15..81e49cb10ed 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 d19cfe605eb..77cabee7cc0 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 81cc59ca559..ed7c5f72cb8 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 63d2ae72406..e185b907fc1 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 -- GitLab From f89271da32bc1a636cf4eb078e615930886cd013 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: [PATCH 1976/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 1 + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 19 +++++++++++++++++++ drivers/infiniband/ulp/ipoib/ipoib_main.c | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 0dcbab3203c..8754b364f22 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 91c95929991..6223fc39af7 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 f217b1edd0a..bfe1dbf9920 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; -- GitLab From 00f7ec36c9324928e4cd23f02e6d8550f30c32ca Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: [PATCH 1977/2509] 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 --- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/core/verbs.c | 46 ++++++++++++++ drivers/infiniband/hw/ehca/ehca_reqs.c | 2 +- drivers/infiniband/hw/ipath/ipath_cq.c | 2 +- drivers/infiniband/hw/ipath/ipath_rc.c | 4 +- drivers/infiniband/hw/ipath/ipath_ruc.c | 4 +- drivers/infiniband/hw/ipath/ipath_uc.c | 8 +-- drivers/infiniband/hw/ipath/ipath_ud.c | 8 +-- drivers/infiniband/hw/mlx4/cq.c | 12 ++-- drivers/infiniband/hw/mthca/mthca_cq.c | 4 +- include/rdma/ib_user_verbs.h | 5 +- include/rdma/ib_verbs.h | 83 ++++++++++++++++++++++++- 12 files changed, 154 insertions(+), 26 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 112b37cd689..56feab6c251 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 9f399d3a42b..e0fbe597586 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 f093b0033da..b799b271021 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 a03bd28d9b4..d385e4168c9 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 108df667d2e..97710522624 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 a4b5521567f..af051f75766 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 0596ec16fcb..82cc588b8bf 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 77ca8ca74e7..36aa242c487 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 4521319b140..299f20832ab 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 f788fce71ac..d9f4735c2b3 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 885254f20bb..a17f7710614 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 5f5621bf70b..74c24b90890 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, @@ -1804,6 +1835,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. -- GitLab From e7e55829999deaab3f43e201a087731c02c54cf9 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: [PATCH 1978/2509] 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 --- drivers/infiniband/hw/cxgb3/cxio_hal.c | 15 ++- drivers/infiniband/hw/cxgb3/cxio_hal.h | 1 + drivers/infiniband/hw/cxgb3/cxio_wr.h | 90 ++++++++++--- drivers/infiniband/hw/cxgb3/iwch_cq.c | 15 ++- drivers/infiniband/hw/cxgb3/iwch_provider.c | 104 +++++++++++++- drivers/infiniband/hw/cxgb3/iwch_provider.h | 8 -- drivers/infiniband/hw/cxgb3/iwch_qp.c | 142 +++++++++++++------- 7 files changed, 293 insertions(+), 82 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 3f441fc57c1..340e4181c76 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 6e128f6bab0..25a880664e6 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 f1a25a821a4..de760e9f1cc 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 4ee8ccd0a9e..cf5474ae68f 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 95f82cfb6c5..5d504f3ed68 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 836163fc542..f5ceca05c43 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 99261379922..3b44300a303 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); -- GitLab From d1f2cd895f8733faa9d79d09d825a2ed80002ac7 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: [PATCH 1979/2509] 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 --- drivers/infiniband/hw/mlx4/qp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 4b0ac5d68c4..76054a72f71 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) -- GitLab From 6578cf33989a594bab37af988d45d87812b946b8 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: [PATCH 1980/2509] 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 --- drivers/infiniband/hw/mlx4/mad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 4c1e72fc8f5..cdca3a511e1 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; -- GitLab From e5a5e7d59af5944a674b9cea420a1fedc60496f2 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: [PATCH 1981/2509] 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 --- drivers/infiniband/core/verbs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index e0fbe597586..a7da9be43e6 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 = { -- GitLab From d3809ad0972297fbc7ef0585049ef465d9d8d79d Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: [PATCH 1982/2509] 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 --- drivers/infiniband/hw/mthca/mthca_qp.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 3b1c5baf13b..77b52b3adcc 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: -- GitLab From 7c27f358209a8ce7c57b584346d7b611e823f1b1 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: [PATCH 1983/2509] 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 --- drivers/infiniband/hw/mlx4/qp.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 76054a72f71..44bbd6c2e31 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: -- GitLab From 3e255eac561672cbc92844b9f16cae9304c2a783 Mon Sep 17 00:00:00 2001 From: Joachim Fenkes Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1984/2509] IB/ehca: Reject receive work requests if QP is in RESET state Signed-off-by: Joachim Fenkes Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_reqs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index b799b271021..dd9bc68f1c7 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, -- GitLab From 6f7bc01a7382641c61ec036d68ff3a9140b48a1c Mon Sep 17 00:00:00 2001 From: Stefan Roscher Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1985/2509] 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 --- drivers/infiniband/hw/ehca/ehca_irq.c | 9 +++++++-- drivers/infiniband/hw/ehca/hcp_if.c | 10 ++++++++++ drivers/infiniband/hw/ehca/hcp_if.h | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index ce1ab0571be..0792d930c48 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 5245e13c3a3..415d3a465de 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 60ce02b7066..2c3c6e0ea5c 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__ */ -- GitLab From 97d1cc8055c7b3fbd35bf693775d61102e65d174 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1986/2509] 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 --- drivers/infiniband/hw/cxgb3/cxio_hal.h | 3 ++- drivers/infiniband/hw/cxgb3/iwch.c | 4 ++-- drivers/infiniband/hw/cxgb3/iwch_provider.c | 25 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 25a880664e6..a9ff32c3621 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 71554eacb13..e09cc1a8199 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 5d504f3ed68..5f438065739 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; -- GitLab From eec8845d29504a12fbd434e192d61aed3d9d74fa Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1987/2509] 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 --- drivers/infiniband/hw/cxgb3/iwch.c | 2 -- drivers/infiniband/hw/cxgb3/iwch.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index e09cc1a8199..06086256ca1 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 d2409a505e8..3773453b2cf 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; -- GitLab From 468f2239bcc71ae0f345c3fe58c797cf4627daf4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1988/2509] RDMA/cma: Add missing newlines to printk()s Signed-off-by: Roland Dreier Acked-by: Sean Hefty --- drivers/infiniband/core/cma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e5bd6172a1f..44d190f6781 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; } -- GitLab From a7d834c4bc6be73e8f83eaa5072fac3c5549f7f2 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: [PATCH 1989/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 63 ++++++++++++++++++------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 6223fc39af7..37bf67b2a26 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) { -- GitLab From 7f624d023b5fb150831e02c1e4c0f2619ade72c2 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1990/2509] 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 --- drivers/infiniband/core/sysfs.c | 120 ++++++++++++++++++++++++++++++++ include/rdma/ib_verbs.h | 53 ++++++++++++++ 2 files changed, 173 insertions(+) diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 36a0ef97c6a..4d104211559 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 74c24b90890..10ebaaae016 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, -- GitLab From 14cc180f7b032f8484c1a3d0533b1129ffe307fd Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1991/2509] 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 --- drivers/infiniband/hw/cxgb3/iwch_provider.c | 62 +++++++++++++++++++-- drivers/net/cxgb3/cxgb3_ctl_defs.h | 1 + drivers/net/cxgb3/cxgb3_offload.c | 7 +++ 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 5f438065739..18a6609f5e0 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 6c4f3206691..ed0ecd9679c 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 ff9c013ce53..cf269687379 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); -- GitLab From 47ee1b9f2e7bf73950602efe0b74fa1a8481f222 Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1992/2509] 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 --- include/rdma/ib_verbs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 10ebaaae016..07b41e05565 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 { -- GitLab From 521e575b9a7324a0bca762622139f69582a042bf Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1993/2509] 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 --- drivers/infiniband/hw/mlx4/main.c | 7 +++++-- drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 ++- drivers/infiniband/hw/mlx4/qp.c | 21 ++++++++++++++++++--- drivers/net/mlx4/mcg.c | 17 +++++++++++++---- include/linux/mlx4/device.h | 3 ++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 4d61e32866c..bcf50648fa1 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 5cf994794d2..c4cf5b69eef 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 44bbd6c2e31..91590e7fba0 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 57f7f1f0d4e..b4b57870ddf 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 a744383d16e..81b3dd5206e 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, -- GitLab From 12406734051a26e9fe4c8568e931dfddbb72d431 Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1994/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 810790ae753..7b8fa36f509 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; -- GitLab From af40da894e96d5c826d38be3ea53ee00d9de0367 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: [PATCH 1995/2509] 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 --- drivers/infiniband/ulp/ipoib/Kconfig | 1 + drivers/infiniband/ulp/ipoib/ipoib.h | 11 ++++ drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | 46 +++++++++++++++ drivers/infiniband/ulp/ipoib/ipoib_ib.c | 8 ++- drivers/infiniband/ulp/ipoib/ipoib_main.c | 62 ++++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig index 1f76bad020f..691525cf394 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 8754b364f22..2c522572e3c 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 10279b79c44..66af5c1a76e 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 eca8518d79a..5d50e5261ee 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 bfe1dbf9920..fead88f7fb1 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. -- GitLab From 038919f29682b00ea95506e959210fc72d1aaf64 Mon Sep 17 00:00:00 2001 From: Joachim Fenkes Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 1996/2509] 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 --- drivers/infiniband/hw/ehca/ehca_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 482103eb6ea..598844d2edc 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", -- GitLab From ee1e2c82c245a5fb2864e9dbcdaab3390fde3fcc Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 1997/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 17 +++++++-- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 42 +++++++++++++-------- drivers/infiniband/ulp/ipoib/ipoib_main.c | 44 ++++++++++++++++++++-- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 18 +++++---- 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 2c522572e3c..bb19587c5ea 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 5d50e5261ee..66cafa20c24 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 fead88f7fb1..b3fd7e8333c 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 7b8fa36f509..96f9aa79cbb 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); } } -- GitLab From 1ff66e8c1faee7c2711b84b9c89e1c5fcd767839 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 1998/2509] 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 --- drivers/infiniband/hw/nes/nes.h | 4 + drivers/infiniband/hw/nes/nes_hw.c | 60 ++------ drivers/infiniband/hw/nes/nes_utils.c | 24 ++++ drivers/infiniband/hw/nes/nes_verbs.c | 189 ++++---------------------- 4 files changed, 66 insertions(+), 211 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 61b46e9c7d2..fe88bec4894 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 d3278f111ca..80e486653ec 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 fe83d1b2b17..8f519c86087 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 d617da9bd35..464a98a6e11 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) -- GitLab From 52c8084b740c42af27d5bfa62cec7079d12fbc2b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 1999/2509] 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 --- drivers/infiniband/hw/cxgb3/cxio_hal.h | 1 + drivers/infiniband/hw/cxgb3/iwch.c | 2 +- drivers/infiniband/hw/cxgb3/iwch_provider.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index a9ff32c3621..656fe47bc84 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 06086256ca1..4489c89d671 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 18a6609f5e0..249d99f4a3c 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; -- GitLab From 8294f29767c53e97664a27db9974adea8e2ea95b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 2000/2509] 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 --- drivers/infiniband/hw/nes/nes.c | 2 +- drivers/infiniband/hw/nes/nes.h | 5 +---- drivers/infiniband/hw/nes/nes_hw.c | 6 +++--- drivers/infiniband/hw/nes/nes_hw.h | 2 +- drivers/infiniband/hw/nes/nes_utils.c | 9 ++++----- drivers/infiniband/hw/nes/nes_verbs.c | 18 +++++++++--------- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a4e9269a29b..d2884e77809 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 fe88bec4894..39bd897b40c 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 80e486653ec..902b1375a5d 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 745bf94f3f0..7b81e0ae007 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 8f519c86087..fb8cbd71a2e 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 464a98a6e11..e3939d13484 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) { -- GitLab From 70fe1796a5ebc5f955be39bba5c42eee9eb89e1f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: [PATCH 2001/2509] RDMA/cxgb3: Set rkey field for new memory windows in iwch_alloc_mw() Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/iwch_provider.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 249d99f4a3c..c9a3893b38e 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); -- GitLab From c03d4731b5b6de45b95a10bf1d510dde423d6757 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: [PATCH 2002/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 1 - drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 8 -------- 2 files changed, 9 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index bb19587c5ea..66a897567ea 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 4a6538b9301..0b7d129161e 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); -- GitLab From 5892eff91ad60ba365ae7f75050ce464036c5396 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: [PATCH 2003/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 1 - drivers/infiniband/ulp/ipoib/ipoib_main.c | 1 - drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 4 ---- 3 files changed, 6 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 66a897567ea..b8753222c87 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 b3fd7e8333c..8be9ea0436e 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 96f9aa79cbb..f50ebe0643e 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); -- GitLab From d0de13622d5ac658efe7c51521dbdbe0752aa3dd Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: [PATCH 2004/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 2 +- .../infiniband/ulp/ipoib/ipoib_multicast.c | 4 ++- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 28 ++++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b8753222c87..7b46e2d7b3c 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 0b7d129161e..55ebd950bf2 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 f50ebe0643e..ba7c8868e6f 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 */ -- GitLab From 9eae554c171e086c89ab83da2a2d3c8bf958fcb5 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: [PATCH 2005/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 2 -- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 6 +++--- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 12 ------------ 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 7b46e2d7b3c..a89b9fbe1ef 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 55ebd950bf2..71add7a8d53 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 ba7c8868e6f..68325119f74 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); -- GitLab From c8c2afe360b7366f586f6bece1109a72ea334876 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:51 -0700 Subject: [PATCH 2006/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 8 ++++++-- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 37bf67b2a26..b4269139135 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 71add7a8d53..be1ed38cdcf 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"); -- GitLab From bd3606715effbf37df986548c43bbed0842b49d5 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:51 -0700 Subject: [PATCH 2007/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index b4269139135..87f9f3ef3b2 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 be1ed38cdcf..1fcc9a898d8 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(); } -- GitLab From df8666198dd058b9498ebdbc52c61957206d30a5 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2008/2509] 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 --- drivers/infiniband/hw/ipath/ipath_mad.c | 6 +++--- drivers/infiniband/hw/ipath/ipath_verbs.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 5f9315d77a4..be4fc9ada8e 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 7779165b2c2..9e23ab0b51a 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; -- GitLab From e112373fd6aa280bd2cbc0d5cc3809115325a1be Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2009/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 7 ++++++- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 12 ++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index a89b9fbe1ef..0281c8fecc9 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 87f9f3ef3b2..0f2d3045061 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; -- GitLab From bc3a290b51aaefc6a6af2d6e6d52ed32387c416c Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2010/2509] 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 --- drivers/infiniband/ulp/ipoib/ipoib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 0281c8fecc9..b0ffc9abe8c 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, -- GitLab From 4522e08ced48baaf28990e2674e940aae9940310 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2011/2509] 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 --- drivers/infiniband/hw/mthca/mthca_catas.c | 15 ++------------- drivers/infiniband/hw/mthca/mthca_dev.h | 1 - 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index 40573e48439..50e2792e60c 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 2997d8d564e..ee4d073c889 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; -- GitLab From c036925ac0e940a4e8525b08e89d2c64fe282c51 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2012/2509] 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 --- drivers/infiniband/hw/mthca/mthca_catas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index 50e2792e60c..cc440f90000 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) -- GitLab From aed012279d35e88e29fd55737d8821604433f50a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: [PATCH 2013/2509] 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 --- drivers/infiniband/hw/mthca/mthca_qp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 77b52b3adcc..f5081bfde6d 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)) { -- GitLab From 96f15c03532282366364ecfd20f04e49b5d96f3a Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2014/2509] 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 --- drivers/infiniband/hw/amso1100/c2_rnic.c | 2 +- drivers/infiniband/hw/cxgb3/iwch_provider.c | 6 ++++-- drivers/infiniband/hw/nes/nes_hw.c | 2 +- include/rdma/ib_verbs.h | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index b1441aeb60c..dd05c483564 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 c9a3893b38e..7ecfd4d638c 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 902b1375a5d..85f26d19a32 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 07b41e05565..90b529f7a15 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; }; -- GitLab From 4ab928f69208d240d3681336f34589e4b151824f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2015/2509] 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 --- drivers/infiniband/hw/cxgb3/cxio_hal.c | 12 +- drivers/infiniband/hw/cxgb3/cxio_wr.h | 13 +- drivers/infiniband/hw/cxgb3/iwch_provider.c | 4 +- drivers/infiniband/hw/cxgb3/iwch_qp.c | 127 +++++++++++++++++--- drivers/net/cxgb3/version.h | 2 +- 5 files changed, 131 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 340e4181c76..f6d5747153a 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 de760e9f1cc..04618f7bfbb 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 7ecfd4d638c..b89640aa6e1 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 3b44300a303..9a3be3a9d5d 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 a0177fc55e2..29db711303b 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 */ -- GitLab From 64c5e613b9dd34ef1281ed6d22478609667ae36a Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2016/2509] 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 --- drivers/infiniband/core/addr.c | 1 + drivers/infiniband/core/cma.c | 8 +++++--- include/rdma/ib_addr.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index e4eb8be3bb0..09a2bec7fd3 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 44d190f6781..5fb506a4177 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 b42bdd00041..483057b2f4b 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; }; /** -- GitLab From de910bd92137005b5e1ecaf2ce68053d7d7d5350 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2017/2509] 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 --- drivers/infiniband/core/cma.c | 106 ++++++++++++++++------------------ 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 5fb506a4177..ae11d5cc74d 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) -- GitLab From 2d92865158d0e21ef4350703af64bc2a610d81d3 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2018/2509] 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 --- drivers/net/mlx4/fw.c | 28 ++++++++++++++++++++++++++++ drivers/net/mlx4/fw.h | 6 ++++++ drivers/net/mlx4/main.c | 7 +++++++ 3 files changed, 41 insertions(+) diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index d82f2751d2c..2b5006b9be6 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 306cb9b0242..a0e046c149b 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 a6aa49fc1d6..d3736013fe9 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"); -- GitLab From f507d28bff0601f1a8a96b7939fa3855c50d25b6 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: [PATCH 2019/2509] 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 --- drivers/infiniband/hw/mlx4/qp.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 91590e7fba0..89eb6cbe592 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); -- GitLab From 089be43e403a78cd6889cde2fba164fefe9dfd89 Mon Sep 17 00:00:00 2001 From: James Morris Date: Tue, 15 Jul 2008 18:32:49 +1000 Subject: [PATCH 2020/2509] 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)" --- security/selinux/hooks.c | 22 +++++----------------- security/selinux/include/security.h | 2 +- security/selinux/ss/services.c | 27 ++++++++------------------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 91200feb3f9..63f131fc42e 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 44cba2e21dc..7c543003d65 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 8e42da12010..b52f923ce68 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: -- GitLab From c9b74c5b8fb807187f6b1db09012828fcd2d7e73 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 18 Apr 2008 20:41:49 +0200 Subject: [PATCH 2021/2509] 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 --- drivers/mmc/host/sdhci.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b413aa6c246..9b06c6042d9 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; -- GitLab From b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Mar 2008 17:35:49 +0100 Subject: [PATCH 2022/2509] 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 --- drivers/mmc/host/Kconfig | 19 +- drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-pci.c | 486 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 499 +++++++---------------------------- drivers/mmc/host/sdhci.h | 82 ++++-- 5 files changed, 651 insertions(+), 436 deletions(-) create mode 100644 drivers/mmc/host/sdhci-pci.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index dead61754ad..f9cbcb891e9 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 3877c87e6da..3027250b855 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 00000000000..2a3dd6cc7bf --- /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 9b06c6042d9..8ce01d434ea 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 299118de893..22fc258b12a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -9,18 +9,6 @@ * your option) any later version. */ -/* - * 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 -- GitLab From 3815a0ebab678c20d0d9c66af5ee9e68807b6681 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 22 Mar 2008 22:05:40 +0100 Subject: [PATCH 2023/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 2a3dd6cc7bf..51798ec5644 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, }, { -- GitLab From 22606405894a3ca5796eb4454a4b83af611fd201 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 23 Mar 2008 19:33:23 +0100 Subject: [PATCH 2024/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 129 +++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 51798ec5644..5094fe80576 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)) { -- GitLab From ee53ab5d73998e502801c024a08de2c39a92c52a Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 5 Jul 2008 00:25:15 +0200 Subject: [PATCH 2025/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 2 +- drivers/mmc/host/sdhci.c | 50 +++++++++++++++++++++--------------- drivers/mmc/host/sdhci.h | 4 +-- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5094fe80576..856bb2b2837 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 8ce01d434ea..95b081a9967 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 22fc258b12a..7ce12f3e745 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 */ -- GitLab From 45211e21598441a32e53cf5032b7faeac143df6d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 24 Mar 2008 13:09:09 +0100 Subject: [PATCH 2026/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 856bb2b2837..ef77ed1bd11 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) -- GitLab From 4489428ab5a49a6f443d9aa17f1d891417787d7b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 4 Apr 2008 19:36:59 +0200 Subject: [PATCH 2027/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 127 ++++++++++++++++++++++++++++++++++- include/linux/pci_ids.h | 1 + 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index ef77ed1bd11..5dcb4958e47 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*); }; @@ -132,6 +138,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 65953822c9c..30153473bc3 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 -- GitLab From 1e72859e3ae16346d4007024b20d2d4ef387dcc3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 16 Apr 2008 19:13:13 +0200 Subject: [PATCH 2028/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 21 ++++++++++++---- drivers/mmc/host/sdhci.c | 48 ++++++++++++++++++++++++++++++------ drivers/mmc/host/sdhci.h | 3 ++- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5dcb4958e47..8554466e0f4 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 95b081a9967..0ab582e77ac 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 7ce12f3e745..7c302515a6a 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); -- GitLab From fd8c326cadd2f781d5c4d6bcee79bb17b3745bb0 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 24 May 2008 22:36:31 +0200 Subject: [PATCH 2029/2509] 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 --- drivers/mmc/card/mmc_test.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index ffadee549a4..371d922d9ee 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); } -- GitLab From 309d9736a903527d8bc41787b07573a054439bf6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 28 May 2008 09:54:50 +0200 Subject: [PATCH 2030/2509] sdhci-pci: unaligned data with ricoh controllers The Ricoh controllers cannot handle unaligned data blocks. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 8554466e0f4..c0fbf48d9b4 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 = { -- GitLab From 150a55683b6b0ccb66aae75a10a3a514340c7c03 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 00:57:27 +0300 Subject: [PATCH 2031/2509] 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 --- include/linux/mmc/mmc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 4236fbf0b6f..14b81f3e523 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 -- GitLab From 28f52482b41edc88cdf575aa6ed414c6e116ce10 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:15 +0400 Subject: [PATCH 2032/2509] 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 --- drivers/mmc/core/core.c | 12 +++++++++--- include/linux/mmc/host.h | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 01ced4c5a61..ede5d1e2e20 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 7ab962fa1d7..6188e19d233 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 */ -- GitLab From 619ef4b42128709de4d89d209b2c874f560deecd Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:21 +0400 Subject: [PATCH 2033/2509] 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 --- drivers/mmc/host/mmc_spi.c | 19 +++++++++++++++++-- include/linux/spi/mmc_spi.h | 9 +++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 35508584ac2..547eb857b1b 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 d5ca78b93a3..a3626aedaec 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; -- GitLab From 08f80bb5196517a0dfe50dc7c10f234c0ff2f0e8 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:39 +0400 Subject: [PATCH 2034/2509] 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 --- drivers/mmc/core/sd.c | 4 ++-- drivers/mmc/host/at91_mci.c | 18 +++++++----------- drivers/mmc/host/imxmmc.c | 9 ++++++--- drivers/mmc/host/mmc_spi.c | 9 ++++++--- drivers/mmc/host/pxamci.c | 9 ++++++--- drivers/mmc/host/wbsd.c | 2 +- include/linux/mmc/host.h | 12 ++++++++++++ 7 files changed, 40 insertions(+), 23 deletions(-) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7ef3b15c5e3..b122eb9ea45 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 8979ad330a4..b9d4ed6b29b 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 eed211b2ac7..5e880c0f134 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 547eb857b1b..4e82f64a96b 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 d89475d3698..d39f5973886 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 c303e7f57ab..67e5a9b80f5 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 6188e19d233..753b7231b88 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); -- GitLab From 8769392b1918ec70ab62eebc82e06c47c12f8304 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 16 Jun 2008 19:20:57 -0700 Subject: [PATCH 2035/2509] 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 --- drivers/mmc/core/mmc.c | 2 +- drivers/mmc/core/sd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 3da29eef8f7..fdd7c760be8 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 b122eb9ea45..26fc098d77c 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, -- GitLab From 80f9254668c63ae73c1359d8de50ad94aa1aa94a Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:05:24 +0200 Subject: [PATCH 2036/2509] 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 --- drivers/mmc/host/at91_mci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b9d4ed6b29b..e40340f32e3 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; } } -- GitLab From e181dce8acab4f7d7c4772d2a8281510d503ab21 Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:06:32 +0200 Subject: [PATCH 2037/2509] 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 --- drivers/mmc/host/at91_mci.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e40340f32e3..fce171c7c67 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); -- GitLab From c5a89c6c0805959f813e8342d6f4040860f6d7db Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:07:47 +0200 Subject: [PATCH 2038/2509] 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 --- drivers/mmc/host/at91_mci.c | 48 ++++++++++++++++++++++++++++ include/asm-arm/arch-at91/at91_mci.h | 4 +++ 2 files changed, 52 insertions(+) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index fce171c7c67..e9242110ce2 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 1551fc24eb4..400ec10014b 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 */ -- GitLab From 4ac24a8722b97d5b4cfc48a4fbd0b2489e358d4d Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:18:57 +0200 Subject: [PATCH 2039/2509] 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 --- drivers/mmc/host/at91_mci.c | 40 +++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e9242110ce2..b5a6e250fc1 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) -- GitLab From 3eb99a7bff3d7459a695f45124a6bbabf31cb4b5 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:08:56 +0200 Subject: [PATCH 2040/2509] 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 --- drivers/mmc/host/at91_mci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b5a6e250fc1..b2bb79e74ea 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; -- GitLab From 7a6588ba20aed4505da912f9dd73616e9bd9ba67 Mon Sep 17 00:00:00 2001 From: Eric Benard Date: Fri, 30 May 2008 14:26:05 +0200 Subject: [PATCH 2041/2509] 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 --- drivers/mmc/host/at91_mci.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b2bb79e74ea..9b546a97aa4 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; -- GitLab From ba7deeed96ca1855c153ad81c45baf6efe1a3362 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:28:45 +0200 Subject: [PATCH 2042/2509] 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 --- drivers/mmc/host/at91_mci.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 9b546a97aa4..e1f91a42d52 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)); -- GitLab From fa1fe010c126ee69f2f75e3a4efc2f6252281ff8 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 10 Jun 2008 11:27:29 +0200 Subject: [PATCH 2043/2509] 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 --- drivers/mmc/host/at91_mci.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e1f91a42d52..e4d018b2fe9 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 -- GitLab From 5385edc50063a2175383ef5e90aa67fb6ab1beae Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Sat, 14 Jun 2008 20:27:20 +0300 Subject: [PATCH 2044/2509] 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 --- drivers/mmc/host/at91_mci.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e4d018b2fe9..d3e96ff4142 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); -- GitLab From 9da3cbaf2881df97e502593c49c93f55eb696091 Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Mon, 9 Jun 2008 22:06:44 +0300 Subject: [PATCH 2045/2509] 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 --- drivers/mmc/host/at91_mci.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index d3e96ff4142..f8c3f7c330e 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)); -- GitLab From 12bd257532708a4d5be4b8548ff121a45ff88f5d Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Mon, 9 Jun 2008 22:06:45 +0300 Subject: [PATCH 2046/2509] 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 --- drivers/mmc/host/at91_mci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index f8c3f7c330e..16df235fcc2 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; -- GitLab From c4223c2c91fa9e5addd6eadd804e57a925ac5e5e Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:36:13 +0200 Subject: [PATCH 2047/2509] 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 --- drivers/mmc/host/au1xmmc.c | 573 +++++++++++++--------- drivers/mmc/host/au1xmmc.h | 9 +- include/asm-mips/mach-au1x00/au1100_mmc.h | 18 +- 3 files changed, 354 insertions(+), 246 deletions(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index cc5f7bc546a..d8776d61b3c 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 341cbdf0bac..3b400654e59 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 9e0028f60a4..c35e2091849 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 -- GitLab From 281dd23ea03e9893c02d237d9e35a7d20d412452 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:37:33 +0200 Subject: [PATCH 2048/2509] au1xmmc: enable 4 bit transfer mode Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman --- drivers/mmc/host/au1xmmc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index d8776d61b3c..2bd4cf42709 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; -- GitLab From 20f522ff5583a818922b3f650f6f7ef0e3e1aa68 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:38:03 +0200 Subject: [PATCH 2049/2509] au1xmmc: SDIO IRQ support. Wire up the SD controllers' SDIO IRQ capability. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman --- drivers/mmc/host/au1xmmc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 2bd4cf42709..16b5640d826 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; -- GitLab From 5c0a889df56c9f6c5a68ec7aa222082569b35fd9 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:38:35 +0200 Subject: [PATCH 2050/2509] 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 --- drivers/mmc/host/au1xmmc.c | 233 ++++++++++++++++++++++--------------- drivers/mmc/host/au1xmmc.h | 97 --------------- 2 files changed, 141 insertions(+), 189 deletions(-) delete mode 100644 drivers/mmc/host/au1xmmc.h diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 16b5640d826..fcbaf40e355 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 3b400654e59..00000000000 --- 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 -- GitLab From 88b8d9a83431237bf3eec1f2968f763607811171 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:39:11 +0200 Subject: [PATCH 2051/2509] 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 --- drivers/mmc/host/au1xmmc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index fcbaf40e355..718eb879587 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); -- GitLab From 08fcb7208c4a8913232e48931783270262ece954 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:40:35 +0200 Subject: [PATCH 2052/2509] au1xmmc: new maintainer. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1528e58b540..f140449ba05 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 -- GitLab From e2d2647702702ea08cb78cdc9eca8c24242aa9be Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Fri, 27 Jun 2008 18:25:18 +0200 Subject: [PATCH 2053/2509] 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 --- drivers/mmc/host/au1xmmc.c | 79 +++++++++----------------------------- 1 file changed, 18 insertions(+), 61 deletions(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 718eb879587..3f15eb20489 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)); -- GitLab From ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 12:52:45 +0200 Subject: [PATCH 2054/2509] 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 --- drivers/mmc/core/core.c | 29 +++++++- drivers/mmc/core/sdio_io.c | 99 ++++++++++++++++++++++++- drivers/net/wireless/libertas/if_sdio.c | 20 ++--- include/linux/mmc/core.h | 1 + include/linux/mmc/sdio_func.h | 4 +- 5 files changed, 137 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ede5d1e2e20..3ee5b8c3b5c 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 @@ -294,6 +294,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 diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 625b92ce9ce..6ee7861fcea 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 3dd537be87d..b54e2ea8346 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 d0c3abed74c..143cebf0586 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 b050f4d7b41..f57f22b3be8 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, -- GitLab From eea0f581c4e596e02250df230f8d385827977964 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 13:22:40 +0200 Subject: [PATCH 2055/2509] 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 --- drivers/mmc/core/sdio_io.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 6ee7861fcea..cc42a41ff6a 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); -- GitLab From 0121a9829bf28c65e1a05cc881899c10d82b8de2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 17:51:27 +0200 Subject: [PATCH 2056/2509] 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 --- drivers/mmc/card/mmc_test.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 371d922d9ee..8e0bb12d048 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); -- GitLab From 93fc48c785f6266e67663b3cbbf24579b53fe5cf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 18:21:41 +0200 Subject: [PATCH 2057/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index c0fbf48d9b4..0716dcffd51 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, -- GitLab From 2134a922c6e75c779983cad5d8aae832275f5a0d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 18:28:51 +0200 Subject: [PATCH 2058/2509] 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 --- drivers/mmc/host/sdhci-pci.c | 17 ++ drivers/mmc/host/sdhci.c | 383 +++++++++++++++++++++++++++++++---- drivers/mmc/host/sdhci.h | 51 ++++- 3 files changed, 407 insertions(+), 44 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 0716dcffd51..deb607c52c0 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 0ab582e77ac..b802044ea94 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); @@ -1236,17 +1503,47 @@ int sdhci_add_host(struct sdhci_host *host) host->flags &= ~SDHCI_USE_DMA; } + 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 7c302515a6a..5bb35528176 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; -- GitLab From 979ce7208a679b8d012450610d5d5aa75aab3af9 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 29 Jun 2008 12:19:47 +0200 Subject: [PATCH 2059/2509] 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 --- drivers/mmc/card/block.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f9ad960d7c1..4b0f8220f15 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. */ -- GitLab From 6b174931a73177c6519f87e6a8d5ae6ba269cdb5 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 30 Jun 2008 09:09:27 +0200 Subject: [PATCH 2060/2509] 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 --- drivers/mmc/card/mmc_test.c | 554 +++++++++++++++++++++++------------- 1 file changed, 364 insertions(+), 190 deletions(-) diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 8e0bb12d048..d6b9b486417 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, }, { -- GitLab From 8f1934ce784bd8f2eaf06f190526500f7f3f9c74 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 30 Jun 2008 21:15:49 +0200 Subject: [PATCH 2061/2509] 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 --- drivers/mmc/host/sdhci.c | 77 +++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b802044ea94..d3e4a391e35 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; -- GitLab From be518018c6b9224c02284fb243207ef741c31ec6 Mon Sep 17 00:00:00 2001 From: Thomas Kleffel Date: Mon, 30 Jun 2008 22:40:24 +0100 Subject: [PATCH 2062/2509] 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 --- drivers/mmc/host/Kconfig | 11 + drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/s3cmci.c | 1343 +++++++++++++++++++++++ drivers/mmc/host/s3cmci.h | 69 ++ include/asm-arm/arch-s3c2410/regs-sdi.h | 20 +- 5 files changed, 1441 insertions(+), 4 deletions(-) create mode 100644 drivers/mmc/host/s3cmci.c create mode 100644 drivers/mmc/host/s3cmci.h diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index f9cbcb891e9..dc88c03662a 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 3027250b855..b3e023bf8c7 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 00000000000..c6a4d3cadf2 --- /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 00000000000..90b8af7d8a4 --- /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 bb9d30b7295..bfb222fa4ab 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) -- GitLab From 679f0f8abd7187baaff40a47fe4733ae4c24cc9a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 30 Jun 2008 22:40:25 +0100 Subject: [PATCH 2063/2509] 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 --- drivers/mmc/host/s3cmci.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index c6a4d3cadf2..4db5bd7c049 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; -- GitLab From ceb3ac252519f9ab318050c8ee842e62820d6731 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 30 Jun 2008 22:40:26 +0100 Subject: [PATCH 2064/2509] 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 --- drivers/mmc/host/s3cmci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 4db5bd7c049..6070f36139b 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); -- GitLab From bdbc9c3a8f7a7956611c970e262693faa95081a5 Mon Sep 17 00:00:00 2001 From: Thomas Kleffel Date: Mon, 30 Jun 2008 22:40:27 +0100 Subject: [PATCH 2065/2509] 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 --- drivers/mmc/host/s3cmci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6070f36139b..8c68b2e0dd6 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) { -- GitLab From d643b5f7e0793ef7828a35a5ea049d675ad2ad8c Mon Sep 17 00:00:00 2001 From: Roman Moracik Date: Mon, 30 Jun 2008 22:40:28 +0100 Subject: [PATCH 2066/2509] 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 --- drivers/mmc/host/s3cmci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 8c68b2e0dd6..774af3d7218 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; -- GitLab From edb5a98e43682d66c98ddd1dee863d867807546e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:29 +0100 Subject: [PATCH 2067/2509] 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 --- drivers/mmc/host/s3cmci.c | 44 ++++++++++++++++++++++++++++-- drivers/mmc/host/s3cmci.h | 1 + include/asm-arm/plat-s3c24xx/mci.h | 12 ++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 include/asm-arm/plat-s3c24xx/mci.h diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 774af3d7218..684a10ca2e8 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 90b8af7d8a4..37d9c60010c 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 00000000000..5be2c1449c6 --- /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 */ -- GitLab From cf0984c8edf63017fcc2ead212ca057877e345df Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:30 +0100 Subject: [PATCH 2068/2509] 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 --- drivers/mmc/host/s3cmci.c | 11 +++++++++-- include/asm-arm/plat-s3c24xx/mci.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 684a10ca2e8..4fd11d8864e 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 5be2c1449c6..4f4ccd18f0c 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; -- GitLab From 7c14450ed6ab4ed453b2bf216ca3aaa7a5402af3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:31 +0100 Subject: [PATCH 2069/2509] 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 --- drivers/mmc/host/s3cmci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 4fd11d8864e..ffd9269a187 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); -- GitLab From 55d70f5a7b25800fc8376cdd81d42d6c201fa91d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:32 +0100 Subject: [PATCH 2070/2509] 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 --- drivers/mmc/host/s3cmci.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index ffd9269a187..aa9a8b44b5e 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); -- GitLab From 3886ff5f63f33c801ed3af265ac0df20d3a8dcf5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:33 +0100 Subject: [PATCH 2071/2509] 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 --- drivers/mmc/host/s3cmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index aa9a8b44b5e..8389107d599 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; -- GitLab From 318f905f02b427b8df33d724b7392a0597b40bdd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:34 +0100 Subject: [PATCH 2072/2509] 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 --- drivers/mmc/host/s3cmci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 8389107d599..a6224f9b28b 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"); -- GitLab From 2de5f79d4dfcb1be16f0b873bc77d6ec74b0426d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:35 +0100 Subject: [PATCH 2073/2509] 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 --- drivers/mmc/host/s3cmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index a6224f9b28b..6f1b474e33b 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; } -- GitLab From 50a845700b3b55f825b0eb901b03d6091f66d9f4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:36 +0100 Subject: [PATCH 2074/2509] 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 --- drivers/mmc/host/s3cmci.c | 19 ++++++++++++++++++- include/asm-arm/plat-s3c24xx/mci.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6f1b474e33b..62d73d3497f 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 4f4ccd18f0c..2d0852ac3b2 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; -- GitLab From ff8c804f1fdecb198c4be57155c61800e0d37bd2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:37 +0100 Subject: [PATCH 2075/2509] 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 --- drivers/mmc/host/s3cmci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 62d73d3497f..2b483953697 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; -- GitLab From 4dde7f755211fd58105c989a99a3a9f2f1238fba Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:38 +0100 Subject: [PATCH 2076/2509] MMC: S3C24XX: Add maintainer entry Add Ben Dooks as S3C24XX SD/MMC driver maintainer. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f140449ba05..9def20aa43b 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 -- GitLab From 7e9c7b64022b7faff6022df64baec8ab467d0bfd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:39 +0100 Subject: [PATCH 2077/2509] 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 --- drivers/mmc/host/s3cmci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 2b483953697..6a1e4994b72 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)) { -- GitLab From 9eeebd22ca757fee8dc10ffe6fa6992f33a3c5ec Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 30 Jun 2008 10:50:23 +0300 Subject: [PATCH 2078/2509] 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 --- drivers/mmc/host/wbsd.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 67e5a9b80f5..c2b61606c43 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 "); -- GitLab From 6d37333163025b46afbcad434ec9a5f2e88e7254 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 30 Jun 2008 10:50:24 +0300 Subject: [PATCH 2079/2509] 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 --- drivers/mmc/core/sdio_io.c | 42 +++++++++++++---------------------- include/linux/mmc/sdio_func.h | 15 +++++-------- 2 files changed, 22 insertions(+), 35 deletions(-) mode change 100644 => 100755 drivers/mmc/core/sdio_io.c mode change 100644 => 100755 include/linux/mmc/sdio_func.h diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c old mode 100644 new mode 100755 index cc42a41ff6a..3ccf6919877 --- 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 f57f22b3be8..28fb0a33acf --- 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, -- GitLab From 7d2be0749a59096a334c94dc48f43294193cb8ed Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 30 Jun 2008 18:35:03 +0200 Subject: [PATCH 2080/2509] 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 --- arch/avr32/boards/atngw100/setup.c | 7 + arch/avr32/boards/atstk1000/atstk1002.c | 3 + arch/avr32/mach-at32ap/at32ap700x.c | 30 +- drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/atmel-mci-regs.h | 91 +++ drivers/mmc/host/atmel-mci.c | 981 ++++++++++++++++++++++++ include/asm-avr32/arch-at32ap/board.h | 6 +- include/asm-avr32/atmel-mci.h | 9 + 9 files changed, 1132 insertions(+), 6 deletions(-) create mode 100644 drivers/mmc/host/atmel-mci-regs.h create mode 100644 drivers/mmc/host/atmel-mci.c create mode 100644 include/asm-avr32/atmel-mci.h diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index a51bb9fb3c8..c7fe94d03a1 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 86b363c1c25..e11659b732f 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 07b21b121ee..021d5121718 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 dc88c03662a..198df423435 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 b3e023bf8c7..2dc9ff23cfb 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 00000000000..a9a5657706c --- /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 00000000000..25d5324ab7e --- /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 b4cddfaca90..a3783861cdd 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 00000000000..c2ea6e1c9aa --- /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 */ -- GitLab From 97067d5581ec831a75a45a52e417bee0f7943dbf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 6 Jul 2008 00:51:07 +0200 Subject: [PATCH 2081/2509] 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 --- drivers/mmc/host/wbsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index c2b61606c43..f7dcd8ec0d7 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; } /* -- GitLab From 23af60398af2f5033e2f53665538a09f498dbc03 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 6 Jul 2008 01:10:27 +0200 Subject: [PATCH 2082/2509] 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 --- drivers/mmc/card/block.c | 47 +++++++++++++++--------------------- drivers/mmc/host/at91_mci.c | 2 +- drivers/mmc/host/atmel-mci.c | 2 +- drivers/mmc/host/mmc_spi.c | 5 +--- drivers/mmc/host/mmci.c | 1 - drivers/mmc/host/omap.c | 2 +- drivers/mmc/host/tifm_sd.c | 2 +- drivers/mmc/host/wbsd.c | 2 +- include/linux/mmc/host.h | 11 ++++----- 9 files changed, 30 insertions(+), 44 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 4b0f8220f15..66e5a5487c2 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 16df235fcc2..f15e2064305 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 25d5324ab7e..cce873c5a14 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 4e82f64a96b..41cc63360e4 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 da5fecad74d..696cf3647ce 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 549517c3567..dbc26eb6a89 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 1c14a186f00..13844843e8d 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 f7dcd8ec0d7..adda3795203 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 753b7231b88..10a2080086c 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 */ -- GitLab From c8b3e02eb250ceb661437e9b198757eff0eb6fd2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sat, 5 Jul 2008 19:52:04 +0300 Subject: [PATCH 2083/2509] 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 --- drivers/mmc/host/sdhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d3e4a391e35..13bd681eda2 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; -- GitLab From c71f65129a1fb67bc6b9b8d03b493675b5c9302b Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 7 Jul 2008 17:25:56 -0400 Subject: [PATCH 2084/2509] 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 --- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 13bd681eda2..17701c3da73 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)) -- GitLab From aba3728ce2e8ce85e1e5f6b275131e9332256789 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 14:48:48 +0200 Subject: [PATCH 2085/2509] x86: sanitize Kconfig Set default n for MEMTEST and MTRR_SANITIZER and fix the help texts. Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6958d6bcaf7..2642b4bf41b 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 -- GitLab From d3af01f18bf18e9b2a95711894fc239daeab5e2e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 15:04:56 +0200 Subject: [PATCH 2086/2509] Documentation: document debugpat commandline option Signed-off-by: Thomas Gleixner --- Documentation/kernel-parameters.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b3a5aad7e62..681d6152e00 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. -- GitLab From 3f1c38723eb467d34d704d0ee6e7b796ba4981ee Mon Sep 17 00:00:00 2001 From: Kevin Winchester Date: Mon, 14 Jul 2008 21:36:13 -0300 Subject: [PATCH 2087/2509] 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 --- include/asm-x86/dwarf2.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index 0bfe250894f..738bb9fb3e5 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 -- GitLab From 62a7573ee9f31d4fdb330b3e68ebf6efaba1d57c Mon Sep 17 00:00:00 2001 From: Benzi Zbit Date: Thu, 10 Jul 2008 02:41:43 +0300 Subject: [PATCH 2088/2509] 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 --- drivers/mmc/core/sdio_cis.c | 6 ++++++ drivers/mmc/core/sdio_io.c | 6 +----- include/linux/mmc/sdio_func.h | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index d5e51b1c7b3..956bd767750 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 3ccf6919877..0888df64581 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 28fb0a33acf..07bee4a0d45 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 */ -- GitLab From ea901300cd8b809285fa5cbced18124f127e0ac6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 10 Jul 2008 03:01:56 +0300 Subject: [PATCH 2089/2509] 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 --- drivers/mmc/core/sdio_io.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 0888df64581..f61fc2d4cd0 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 */ } /** -- GitLab From 6a36913a33cf3d366e124f25c486a71212d02bce Mon Sep 17 00:00:00 2001 From: Sascha Sommer Date: Tue, 15 Jul 2008 14:21:29 +0200 Subject: [PATCH 2090/2509] mmc: host driver for Ricoh Bay1Controllers Signed-off-by: Sascha Sommer Signed-off-by: Pierre Ossman --- MAINTAINERS | 6 + drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 2 + drivers/mmc/host/sdricoh_cs.c | 575 ++++++++++++++++++++++++++++++++++ 4 files changed, 593 insertions(+) create mode 100644 drivers/mmc/host/sdricoh_cs.c diff --git a/MAINTAINERS b/MAINTAINERS index 9def20aa43b..c16b986d7e0 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 198df423435..dc6f2579f85 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 2dc9ff23cfb..db52eebfb50 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 00000000000..f99e9f72162 --- /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)"); -- GitLab From c43d8636971c39da993e94082fd65bfff421618e Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 10 Jul 2008 12:28:48 +0100 Subject: [PATCH 2091/2509] 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 --- drivers/mmc/card/sdio_uart.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index eeea84c309e..78ad48718ab 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) -- GitLab From fe9233fb6914a0eb20166c967e3020f7f0fba2c9 Mon Sep 17 00:00:00 2001 From: Chandra Seetharaman Date: Fri, 23 May 2008 18:16:40 -0700 Subject: [PATCH 2092/2509] [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 --- drivers/md/Kconfig | 6 +++++- drivers/md/dm-mpath.c | 2 ++ include/scsi/scsi_dh.h | 12 +++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index b4a3c7d1451..07d92c11b5d 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 e8f704aa46f..9f7302d4878 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 04d0d8495c8..3ad2303d1a1 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 -- GitLab From 1e51764a3c2ac05a23a22b2a95ddee4d9bffb16d Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:37 +0300 Subject: [PATCH 2093/2509] 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 --- fs/ubifs/budget.c | 731 ++++++++++ fs/ubifs/commit.c | 677 +++++++++ fs/ubifs/compress.c | 253 ++++ fs/ubifs/debug.c | 2289 +++++++++++++++++++++++++++++++ fs/ubifs/debug.h | 403 ++++++ fs/ubifs/dir.c | 1240 +++++++++++++++++ fs/ubifs/file.c | 1275 +++++++++++++++++ fs/ubifs/find.c | 975 +++++++++++++ fs/ubifs/gc.c | 773 +++++++++++ fs/ubifs/io.c | 914 +++++++++++++ fs/ubifs/ioctl.c | 204 +++ fs/ubifs/journal.c | 1387 +++++++++++++++++++ fs/ubifs/key.h | 533 ++++++++ fs/ubifs/log.c | 805 +++++++++++ fs/ubifs/lprops.c | 1357 ++++++++++++++++++ fs/ubifs/lpt.c | 2243 ++++++++++++++++++++++++++++++ fs/ubifs/lpt_commit.c | 1648 ++++++++++++++++++++++ fs/ubifs/master.c | 387 ++++++ fs/ubifs/misc.h | 342 +++++ fs/ubifs/orphan.c | 958 +++++++++++++ fs/ubifs/recovery.c | 1519 +++++++++++++++++++++ fs/ubifs/replay.c | 1075 +++++++++++++++ fs/ubifs/sb.c | 629 +++++++++ fs/ubifs/scan.c | 362 +++++ fs/ubifs/shrinker.c | 322 +++++ fs/ubifs/super.c | 1951 ++++++++++++++++++++++++++ fs/ubifs/tnc.c | 2956 ++++++++++++++++++++++++++++++++++++++++ fs/ubifs/tnc_commit.c | 1103 +++++++++++++++ fs/ubifs/tnc_misc.c | 494 +++++++ fs/ubifs/ubifs-media.h | 745 ++++++++++ fs/ubifs/ubifs.h | 1649 ++++++++++++++++++++++ fs/ubifs/xattr.c | 581 ++++++++ 32 files changed, 32780 insertions(+) create mode 100644 fs/ubifs/budget.c create mode 100644 fs/ubifs/commit.c create mode 100644 fs/ubifs/compress.c create mode 100644 fs/ubifs/debug.c create mode 100644 fs/ubifs/debug.h create mode 100644 fs/ubifs/dir.c create mode 100644 fs/ubifs/file.c create mode 100644 fs/ubifs/find.c create mode 100644 fs/ubifs/gc.c create mode 100644 fs/ubifs/io.c create mode 100644 fs/ubifs/ioctl.c create mode 100644 fs/ubifs/journal.c create mode 100644 fs/ubifs/key.h create mode 100644 fs/ubifs/log.c create mode 100644 fs/ubifs/lprops.c create mode 100644 fs/ubifs/lpt.c create mode 100644 fs/ubifs/lpt_commit.c create mode 100644 fs/ubifs/master.c create mode 100644 fs/ubifs/misc.h create mode 100644 fs/ubifs/orphan.c create mode 100644 fs/ubifs/recovery.c create mode 100644 fs/ubifs/replay.c create mode 100644 fs/ubifs/sb.c create mode 100644 fs/ubifs/scan.c create mode 100644 fs/ubifs/shrinker.c create mode 100644 fs/ubifs/super.c create mode 100644 fs/ubifs/tnc.c create mode 100644 fs/ubifs/tnc_commit.c create mode 100644 fs/ubifs/tnc_misc.c create mode 100644 fs/ubifs/ubifs-media.h create mode 100644 fs/ubifs/ubifs.h create mode 100644 fs/ubifs/xattr.c diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c new file mode 100644 index 00000000000..d81fb9ed2b8 --- /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 00000000000..3b516316c9b --- /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 00000000000..5bb51dac3c1 --- /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 00000000000..4e3aaeba4ec --- /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 00000000000..3c4f1e93c9e --- /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 00000000000..e90374be7d3 --- /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 00000000000..005a3b854d9 --- /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 00000000000..10394c54836 --- /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 00000000000..d0f3dac2908 --- /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 00000000000..3374f91b670 --- /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 00000000000..5e82cffe969 --- /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 00000000000..283155abe5f --- /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 00000000000..8f747600754 --- /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 00000000000..36857b9ed59 --- /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 00000000000..2ba93da71b6 --- /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 00000000000..9ff2463177e --- /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 00000000000..5f0b83e20af --- /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 00000000000..71d5493bf56 --- /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 00000000000..4beccfc256d --- /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 00000000000..3afeb9242c6 --- /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 00000000000..77d26c141cf --- /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 00000000000..7399692af85 --- /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 00000000000..2bf753b3888 --- /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 00000000000..acf5c5fffc6 --- /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 00000000000..f248533841a --- /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 00000000000..00eb9c68ad0 --- /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 00000000000..e909f4a9644 --- /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 00000000000..8117e65ba2e --- /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 00000000000..a25c1cc1f8d --- /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 00000000000..0cc7da9bed4 --- /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 00000000000..e4f89f27182 --- /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 00000000000..1388a078e1a --- /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; +} -- GitLab From 0d7eff873caaeac84de01a1acdca983d2c7ba3fe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:38 +0300 Subject: [PATCH 2094/2509] UBIFS: include to compilation Add UBIFS to Makefile and Kbuild. Signed-off-by: Artem Bityutskiy Signed-off-by: Adrian Hunter --- fs/Kconfig | 3 ++ fs/Makefile | 1 + fs/ubifs/Kconfig | 72 +++++++++++++++++++++++++++++++++++++++++++++++ fs/ubifs/Makefile | 9 ++++++ 4 files changed, 85 insertions(+) create mode 100644 fs/ubifs/Kconfig create mode 100644 fs/ubifs/Makefile diff --git a/fs/Kconfig b/fs/Kconfig index 2694648cbd1..a52cf6280b4 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 1e7a11bd4da..fcae06aaadc 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 00000000000..91ceeda7e5b --- /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 00000000000..80e93c35e49 --- /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 -- GitLab From 7890ea1f95fa8968fa6f5bb5860e6632932abfd3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 15 Jul 2008 23:46:24 +0800 Subject: [PATCH 2095/2509] Revert crypto: prng - Deterministic CPRNG This patch is clearly not ready yet for prime time. Signed-off-by: Herbert Xu --- crypto/Kconfig | 9 -- crypto/Makefile | 2 +- crypto/prng.c | 410 ------------------------------------------------ crypto/prng.h | 27 ---- 4 files changed, 1 insertion(+), 447 deletions(-) delete mode 100644 crypto/prng.c delete mode 100644 crypto/prng.h diff --git a/crypto/Kconfig b/crypto/Kconfig index ea503572fcb..d83185915ee 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 ef61b3b6466..d4f3ed857df 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 24e4f3282c5..00000000000 --- 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 1ac9be5009b..00000000000 --- 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 - -- GitLab From 0937502af7c9b648ed4e884ccb7f504b01a005a1 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 28 May 2008 10:32:22 -0700 Subject: [PATCH 2096/2509] 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 --- mm/slub.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/slub.c b/mm/slub.c index 5f6e2c4a2ba..b3f2e713cdf 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; } -- GitLab From 88e4ccf294ca62c2da998012a83533ce150c8dce Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 23 Jun 2008 02:58:37 +0400 Subject: [PATCH 2097/2509] slub: current is always valid Acked-by: Christoph Lameter Signed-off-by: Alexey Dobriyan Signed-off-by: Pekka Enberg --- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index b3f2e713cdf..488400d1070 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)); -- GitLab From e79aec291da55aa322ddb5d8f3bb04cdf69470d5 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 4 Jul 2008 00:40:32 +0530 Subject: [PATCH 2098/2509] 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 --- mm/slab.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 046607f05f3..b4aa4c88250 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; -- GitLab From 2954c02a884dc0ba9e91882c0aba13bcb9d22e6c Mon Sep 17 00:00:00 2001 From: "Chen, Huacai" Date: Tue, 10 Jun 2008 09:05:08 +0800 Subject: [PATCH 2099/2509] [MIPS] modify the MIPS CPU classfication Signed-off-by: Huacai Chen Signed-off-by: Ralf Baechle --- include/asm-mips/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 1c35cac6f35..229a786101d 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 -- GitLab From cb11dfa0247df479e384c4a7ab6846f3a6bf1570 Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 9 Jun 2008 16:30:03 -0700 Subject: [PATCH 2100/2509] [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 --- arch/mips/kernel/traps.c | 6 ------ include/asm-mips/traps.h | 1 - 2 files changed, 7 deletions(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index f9165d1a17b..6e7e4a2775f 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 e5dbde625ec..90ff2f497c5 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 */ -- GitLab From c88a8b4ab0e1a1f06938939d9ba42e9da6144ccb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 9 Jun 2008 17:19:53 +0100 Subject: [PATCH 2101/2509] [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 --- arch/mips/jazz/setup.c | 1 - arch/mips/kernel/setup.c | 7 ------- arch/mips/pci/pci-bcm1480.c | 2 -- arch/mips/pci/pci-sb1250.c | 3 --- arch/mips/sni/setup.c | 1 - include/asm-mips/io.h | 17 ----------------- 6 files changed, 31 deletions(-) diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index a7947199c99..f136c8a8591 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 c6a063b2a0d..c04e4e3afed 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 87e2c8f54e2..d19d262157f 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 2a09ad91ec8..9bc102a1380 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 5484e1c6205..a49272ce7ef 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 f18d2816cbe..501a40b9f18 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -160,13 +160,6 @@ static inline void * isa_bus_to_virt(unsigned long address) #define virt_to_bus virt_to_phys #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. */ @@ -527,16 +520,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int memcpy((void __force *) dst, src, count); } -/* - * 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 -- GitLab From 07cdb78436d52416a582e645b9afb6e26f986bc9 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:08 +0300 Subject: [PATCH 2102/2509] [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 --- arch/mips/kernel/early_printk.c | 2 ++ arch/mips/kernel/setup.c | 6 +----- include/asm-mips/setup.h | 2 ++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c index 9dccfa4752b..9ae813eb782 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 c04e4e3afed..8af84867e74 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 70009a90263..883f59bfa09 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 */ -- GitLab From 17f61e61b4a1d3ca254668cf12c1c5d828d892fd Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:09 +0300 Subject: [PATCH 2103/2509] [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 --- arch/mips/mm/uasm.c | 4 ++-- arch/mips/mm/uasm.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 1655aa69e13..f467199676a 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 0d6a66f3203..c6d1e3dd82d 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); -- GitLab From f366e2085f28358a5294b8cdc847a377c02eb22d Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:11 +0300 Subject: [PATCH 2104/2509] [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 --- arch/mips/kernel/irq.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index e3309ff9ece..6045b9a51a3 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. -- GitLab From 4b62220b608ab71876d8920d5590f1db4ee2eb4a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:29 +0100 Subject: [PATCH 2105/2509] [MIPS] Alchemy, PNX: Use symbolic constants for DMA masks. Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/platform.c | 29 +++++++++++++------------ arch/mips/au1000/pb1200/platform.c | 5 +++-- arch/mips/nxp/pnx8550/common/platform.c | 9 ++++---- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 74d6d4a593b..dc8a67efac2 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 5930110b9b6..f8fb0aeac57 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 c7c763dbe58..21d2955359b 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), -- GitLab From 997288517ec839b7639fcba77111256b13a66000 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:39:58 +0200 Subject: [PATCH 2106/2509] [MIPS] Alchemy: remove unused MMC macros from db1x00 header. Signed-off-by: Manuel Lauss Signed-off-by: Ralf Baechle --- include/asm-mips/mach-db1x00/db1x00.h | 45 --------------------------- 1 file changed, 45 deletions(-) diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h index 612ae90dbcb..1a515b8c870 100644 --- a/include/asm-mips/mach-db1x00/db1x00.h +++ b/include/asm-mips/mach-db1x00/db1x00.h @@ -145,51 +145,6 @@ typedef volatile struct #define SET_VCC_VPP(VCC, VPP, SLOT)\ ((((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 * -- GitLab From 2957c9e61ee9c37e7ebf2c8acab03e073fe942fd Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:30 +0100 Subject: [PATCH 2107/2509] [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 --- arch/mips/Kconfig | 4 - arch/mips/kernel/Makefile | 4 - arch/mips/kernel/irix5sys.S | 1041 ---------------- arch/mips/kernel/irixelf.c | 1361 -------------------- arch/mips/kernel/irixinv.c | 78 -- arch/mips/kernel/irixioctl.c | 213 ---- arch/mips/kernel/irixsig.c | 888 ------------- arch/mips/kernel/process.c | 7 - arch/mips/kernel/scall32-o32.S | 19 - arch/mips/kernel/sysirix.c | 2140 -------------------------------- include/asm-mips/inventory.h | 24 - include/asm-mips/namei.h | 25 +- include/asm-mips/prctl.h | 41 - include/asm-mips/signal.h | 3 - 14 files changed, 5 insertions(+), 5843 deletions(-) delete mode 100644 arch/mips/kernel/irix5sys.S delete mode 100644 arch/mips/kernel/irixelf.c delete mode 100644 arch/mips/kernel/irixinv.c delete mode 100644 arch/mips/kernel/irixioctl.c delete mode 100644 arch/mips/kernel/irixsig.c delete mode 100644 arch/mips/kernel/sysirix.c delete mode 100644 include/asm-mips/inventory.h delete mode 100644 include/asm-mips/prctl.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 24c5dee9176..21d6ec1e536 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 65e46a6d417..48ae915b38e 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 eeef891093e..00000000000 --- 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 469c7237e5b..00000000000 --- 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 cf2dcd3d6a9..00000000000 --- 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 b39bdba82e0..00000000000 --- 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 0215c805a59..00000000000 --- 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 2c09a442e5e..c06f5b5d764 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 08a9c5070ea..c058c0b61a2 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 c357762b801..00000000000 --- 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 cc88aed23f0..00000000000 --- 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 c94d12d1f86..a6605a75246 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 8121a9a75bf..00000000000 --- 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 7a28989f7ee..bee5153aca4 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 */ -- GitLab From 52f4f6bbcff5510f662a002ec1219660ea25af62 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 12 Jun 2008 15:20:05 -0400 Subject: [PATCH 2108/2509] [MIPS] Use kernel-supplied ARRAY_SIZE() macro. Signed-off-by: Robert P. J. Day Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/malta/malta_int.c | 2 +- arch/mips/sgi-ip22/ip28-berr.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 8c495104b32..4b5694e19d3 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 30e12e2ec4b..fee7a2e0e53 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", -- GitLab From 043ebd6c9de7500a399017643bbc5cafd4e37060 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 13 Jun 2008 00:25:36 +0100 Subject: [PATCH 2109/2509] [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 --- include/asm-mips/dec/kn05.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h index 15fe8f881e6..56d22dc8803 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 */ -- GitLab From 94daeb90698c56a85ed219eeb18d4a8cddde7b03 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 11 Jun 2008 10:04:25 -0700 Subject: [PATCH 2110/2509] [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 --- include/asm-mips/bitops.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 642724734eb..9a7274ba6a0 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) { -- GitLab From f2bc713f15103372c0efab5fc09dd813655c5096 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 26 Jun 2008 21:52:51 +0900 Subject: [PATCH 2111/2509] [MIPS] Cobalt: Register new LCD platform device. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/cobalt/Makefile | 2 +- arch/mips/cobalt/lcd.c | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 arch/mips/cobalt/lcd.c diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index d73833b7c78..237926288d6 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 00000000000..0720e4fae31 --- /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); -- GitLab From 8736595bb2b0ce6188ca31308c40921f3f02f35b Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 2 Jul 2008 21:06:03 +0200 Subject: [PATCH 2112/2509] [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 --- arch/mips/pci/ops-mace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c index e95881897ec..1cfb5588699 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); -- GitLab From 1ea6428cbdbb0fd1a6e7e8c3044253eab9aff4c7 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:19 +0300 Subject: [PATCH 2113/2509] [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 --- arch/mips/kernel/i8253.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 38fa1a194bf..b6ac55162b9 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, -- GitLab From d58eaab5a01b9cf1819ec57271ac214a39bf6278 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:20 +0300 Subject: [PATCH 2114/2509] [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 --- arch/mips/pci/pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 358ad621094..d7d6cb063d2 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; -- GitLab From 7afed6a6c92fadedde8474bbfd92d6debc5e23b0 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:21 +0300 Subject: [PATCH 2115/2509] [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 --- arch/mips/mips-boards/malta/malta_int.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 4b5694e19d3..b393982c0cc 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); -- GitLab From 6ccab43b49beced70d8663b47ab471c4a23cb580 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:22 +0300 Subject: [PATCH 2116/2509] [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 --- arch/mips/mips-boards/malta/malta_int.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index b393982c0cc..ea176113fea 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; -- GitLab From c3dd3de789630b9b1ac8f5175f1c21bbf1cca939 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:23 +0300 Subject: [PATCH 2117/2509] [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 --- arch/mips/mips-boards/generic/display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c index 2a0057cfc30..7c8828fcb0a 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; -- GitLab From 7a2852e49fe2d19296812c0f0f833b0ee3043bbb Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 18 Mar 2008 22:47:56 +0100 Subject: [PATCH 2118/2509] [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 --- arch/mips/sgi-ip22/ip22-mc.c | 26 ++++++++++++++++++++++++++ include/asm-mips/barrier.h | 14 ++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 3f35d6367be..5268ac187bb 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 9d8cfbb5e79..8e9ac313ca3 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 -- GitLab From 8fa9cc16f820915fbe8ab6047c420703a87c307e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 5 Jul 2008 01:12:13 +0200 Subject: [PATCH 2119/2509] [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 --- arch/mips/sgi-ip32/ip32-platform.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 89a71f49b69..2ee401ba0b2 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"); -- GitLab From af3e69cfc9644c742a22647a5091779b9dfb9653 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 4 Jul 2008 00:59:40 +0900 Subject: [PATCH 2120/2509] [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 --- arch/mips/pci/fixup-vr4133.c | 1 - arch/mips/pci/pci-bcm1480.c | 1 - arch/mips/pci/pci-ip27.c | 1 - arch/mips/pci/pci-sb1250.c | 1 - include/asm-mips/pci.h | 3 +++ 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c index de5e5f6bbf4..34e651bd2b5 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 d19d262157f..a9060c77184 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 a18516925cd..ce92f82b16d 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 9bc102a1380..bf639590b8b 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 301ff2f2801..d3be8343607 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 */ -- GitLab From b29eee4935d9e5952a7ea8543ea499f06fb86808 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 16 Apr 2008 02:00:45 +0900 Subject: [PATCH 2121/2509] [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 --- arch/mips/pci/fixup-rbtx4927.c | 1 - arch/mips/pci/ops-tx4927.c | 5 +- arch/mips/tx4927/common/tx4927_dbgio.c | 5 +- arch/mips/tx4927/common/tx4927_prom.c | 8 +- .../toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 234 +------------ .../toshiba_rbtx4927/toshiba_rbtx4927_prom.c | 7 +- .../toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 322 +----------------- include/asm-mips/tx4927/toshiba_rbtx4927.h | 4 - include/asm-mips/tx4927/tx4927.h | 240 ++++++++++++- include/asm-mips/tx4927/tx4927_pci.h | 268 --------------- 10 files changed, 266 insertions(+), 828 deletions(-) delete mode 100644 include/asm-mips/tx4927/tx4927_pci.h diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 7450c335b38..2d234ca017d 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 150419c8b41..1bbafeb4a77 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 d8423e001b2..ea1ff23f4b7 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 6eed53d8f38..cc2aa9d63e8 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 6d31f2a98ab..c18901a75cc 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 f3f86857bea..fdbad4bc602 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 2203c77b2ce..185f303c0e2 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 b188a659ce0..d6b32acd6b7 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 193e80a17c1..1d4816f3266 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 0be77df70f2..00000000000 --- 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 */ -- GitLab From b012cffe7f6971e9ba5afca034a3d80e1cf1435c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [PATCH 2122/2509] [MIPS] Replace use of print_symbol with new %sP pointer format. Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips-mt.c | 11 +++++------ arch/mips/kernel/traps.c | 8 ++++---- arch/mips/sgi-ip27/ip27-nmi.c | 10 +++------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index 640fb0cc6e3..d01665a453f 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 6e7e4a2775f..b8ea4e9d0d8 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 b0a25e1ee8b..64459e7d891 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) -- GitLab From 74c8494eeb7b321e5922ee43120f91c7c9b7317f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [PATCH 2123/2509] [MIPS] Bigsur: Make defconfig a bit more useful. Signed-off-by: Ralf Baechle --- arch/mips/configs/bigsur_defconfig | 162 ++++++++++++++++++----------- 1 file changed, 104 insertions(+), 58 deletions(-) diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 3b42cea2e40..2b4ad5f3e95 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 @@ -913,13 +929,6 @@ CONFIG_I2C=y 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 # @@ -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 -- GitLab From 372a775f50347f5c1dd87752b16e5c05ea965790 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [PATCH 2124/2509] [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 --- arch/mips/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ad36c946ff9..0b8d82d55c6 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. -- GitLab From 2157bc68711bf0e69f9aca4d310bd863298fbb3f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [PATCH 2125/2509] [MIPS] Atlas: Remove support code. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 32 - arch/mips/Makefile | 9 - arch/mips/configs/atlas_defconfig | 1472 -------------------- arch/mips/configs/bcm47xx_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/fulong_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip28_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/lasat_defconfig | 1 - arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/msp71xx_defconfig | 1 - arch/mips/configs/mtx1_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 1 - arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/mips-boards/atlas/Makefile | 22 - arch/mips/mips-boards/atlas/atlas_gdb.c | 97 -- arch/mips/mips-boards/atlas/atlas_int.c | 272 ---- arch/mips/mips-boards/atlas/atlas_setup.c | 82 -- arch/mips/mips-boards/generic/console.c | 11 +- arch/mips/mips-boards/generic/init.c | 8 - arch/mips/mips-boards/generic/reset.c | 17 - arch/mips/mips-boards/generic/time.c | 5 +- arch/mips/pci/Makefile | 1 - arch/mips/pci/fixup-atlas.c | 91 -- include/asm-mips/mach-atlas/mc146818rtc.h | 60 - 56 files changed, 2 insertions(+), 2219 deletions(-) delete mode 100644 arch/mips/configs/atlas_defconfig delete mode 100644 arch/mips/mips-boards/atlas/Makefile delete mode 100644 arch/mips/mips-boards/atlas/atlas_gdb.c delete mode 100644 arch/mips/mips-boards/atlas/atlas_int.c delete mode 100644 arch/mips/mips-boards/atlas/atlas_setup.c delete mode 100644 arch/mips/pci/fixup-atlas.c delete mode 100644 include/asm-mips/mach-atlas/mc146818rtc.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 21d6ec1e536..6383c700686 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 0b8d82d55c6..9bc2c763909 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -309,15 +309,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 # diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig deleted file mode 100644 index 3443f6cd57b..00000000000 --- 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 c0e42e74dfb..10d83e4aca5 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 2b4ad5f3e95..a9926861f14 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 a94f14b5c8f..ee8a7fc99f5 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 b7295e98838..ce31a47f1a1 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 36578968d38..f99b6f8c978 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 5a90740c363..0d6ba9e65ff 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 76f37a1159f..0c6f2a469f0 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 508c91944f3..02db28f5dc0 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 0c2c70d21db..a0f19f2e7d5 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 58c2cd68c3a..c1ab8a21bb0 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 90d81f5dceb..88c2420bc62 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 f9a003c2b3a..03f0baad1b6 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 15efacc75d7..873597a4aaf 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 5887a1735fb..13e1ef2240e 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 4f5e56c9335..7daf203c148 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 f40e437bd9e..83d769f941d 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 ec188be9a67..3c5090a248b 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 2c5c624c5d4..f8d1cf3e874 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 56148745e8f..72ff710c878 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 a7cd67753aa..8dc8bef471b 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 e6aef999854..a8fa2055c07 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 3d0da952811..9a8ed74cc1a 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 4f6bce99d5c..1d205446ee7 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 27e23fc9363..0c7f35acb70 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 b12b73f6d74..2dd2a4f38fb 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 fa3aa391944..17d66526fa4 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 1d0157d3a5b..eaf608ca65a 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 d0491a05ee5..62c5a7098ab 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 16d78d3cd2a..29c8548b68f 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 780c7fc24b8..c714f43e7dc 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 267f21ed1d0..c1adcfac6c5 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 470f6f4d3ea..9e108362629 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 5a39f56b175..462a652ee02 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 56371b860eb..2562f355dbf 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 4b879980278..ff89765f87f 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 3ee75b15c0b..d3db59bf399 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 8dd3ae39bca..34ce11de536 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 2ba240e897c..e5ae6b1839b 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 a5d0f3c55ed..2fdfd6659ef 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 edf90b321fe..ee411216d37 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 2e3c683b205..66d3c11a038 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 b6178ffbc52..daa4e48a723 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 f71c2dd1041..00000000000 --- 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 00c98cff62d..00000000000 --- 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 6fb29c3ff62..00000000000 --- 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 5c500802271..00000000000 --- 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 4d8ab99e415..4a2aecc6da1 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 83b9dc73920..bac23b5fbf3 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 583d468d98a..5f73ff6180e 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 fe2cac1b451..d224267846b 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 ed0c07622ba..80fa5abb25d 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 506e883a8c7..00000000000 --- 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 51d337e1bbd..00000000000 --- 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 */ -- GitLab From 1398ddb2ebdb41e8efe6ba42505fd452704c8405 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [PATCH 2126/2509] [MIPS] SEAD: Remove support code. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 20 - arch/mips/Makefile | 8 - arch/mips/configs/bcm47xx_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/fulong_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip28_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/lasat_defconfig | 1 - arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/msp71xx_defconfig | 1 - arch/mips/configs/mtx1_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 641 --------------------- arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/mips-boards/generic/console.c | 12 - arch/mips/mips-boards/generic/init.c | 4 - arch/mips/mips-boards/generic/reset.c | 2 +- arch/mips/mips-boards/generic/time.c | 5 +- arch/mips/mips-boards/sead/Makefile | 28 - arch/mips/mips-boards/sead/sead_int.c | 117 ---- arch/mips/mips-boards/sead/sead_setup.c | 77 --- include/asm-mips/mips-boards/generic.h | 9 - 52 files changed, 2 insertions(+), 962 deletions(-) delete mode 100644 arch/mips/configs/sead_defconfig delete mode 100644 arch/mips/mips-boards/sead/Makefile delete mode 100644 arch/mips/mips-boards/sead/sead_int.c delete mode 100644 arch/mips/mips-boards/sead/sead_setup.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6383c700686..a0381427ec5 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 9bc2c763909..800a73db822 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -317,14 +317,6 @@ cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips 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 # diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 10d83e4aca5..d8694332b34 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 a9926861f14..a3bbbf067a3 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 ee8a7fc99f5..185df23fd46 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 ce31a47f1a1..2678b7ec335 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 f99b6f8c978..ebb8ad62b3a 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 0d6ba9e65ff..ad4e5ef6559 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 0c6f2a469f0..d0dc2e83ad3 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 02db28f5dc0..9155082313c 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 a0f19f2e7d5..e4e324422cd 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 c1ab8a21bb0..9e65e6a2dcb 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 88c2420bc62..1bd84d42b14 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 03f0baad1b6..634bb4eaf13 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 873597a4aaf..3572e80356d 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 13e1ef2240e..620980081a3 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 7daf203c148..cc8e6bf2b24 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 83d769f941d..138c575a015 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 3c5090a248b..822b01f643e 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 f8d1cf3e874..fe4699df962 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 72ff710c878..bbacc35d804 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 8dc8bef471b..92000a3a871 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 a8fa2055c07..bc9159fda72 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 9a8ed74cc1a..55288cf50b7 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 1d205446ee7..2c0a6314e90 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 0c7f35acb70..8c720e51795 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 2dd2a4f38fb..59d19472b16 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 17d66526fa4..bacf0dd0e34 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 eaf608ca65a..6dfe6f793ce 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 62c5a7098ab..c965a87e6a9 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 29c8548b68f..0778996c682 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 c714f43e7dc..37c7b5ffd47 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 c1adcfac6c5..893e5c4ab66 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 9e108362629..f89482a2aa6 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 462a652ee02..70cf6976167 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 2562f355dbf..0f4da0325ea 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 ff89765f87f..1ea97865f2c 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 d3db59bf399..00000000000 --- 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 34ce11de536..b5059881bc7 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 e5ae6b1839b..b06a716bf23 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 2fdfd6659ef..46512cf7ce0 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 ee411216d37..b437eb7f867 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 66d3c11a038..fc2c56731b9 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 daa4e48a723..7f86c43d1bd 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 4a2aecc6da1..43bcfb4f816 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 bac23b5fbf3..c0653021a17 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 5f73ff6180e..ea932b84396 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 d224267846b..637897e8e4f 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 3682fe217bd..00000000000 --- 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 ec6dd194c14..00000000000 --- 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 8aa8e5b7b07..00000000000 --- 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 33407bee4e7..7f0b034dd9a 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. -- GitLab From 6da5e30b879394f0c55b2bbf3353d797097c8f0f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [PATCH 2127/2509] [MIPS] Remove impossible ifdef and code wrapped by it. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/generic/time.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 637897e8e4f..744dbfc6e48 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; -- GitLab From d5deda6fa1ca434d36c2daffb63127e92c6470f5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [PATCH 2128/2509] [MIPS] MSC01: Cleanup configuration. This shouldn't depend on CONFIG_MIPS_BOARDS_GEN which is about to go away. Signed-off-by: Ralf Baechle --- arch/mips/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 48ae915b38e..0fd31974ba2 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 -- GitLab From eda49eeebf263f3a34f6968959fc2e4825b42beb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [PATCH 2129/2509] [MIPS] Remove always true ifdef conditions. Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 8 ++------ arch/mips/configs/malta_defconfig | 1 - arch/mips/mips-boards/generic/memory.c | 6 ------ arch/mips/mips-boards/generic/reset.c | 2 -- arch/mips/mips-boards/generic/time.c | 4 ---- 5 files changed, 2 insertions(+), 19 deletions(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 800a73db822..ed8821ac8a8 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -304,15 +304,11 @@ core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/ 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 55288cf50b7..74daa0cf87e 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 5e443bba566..61888ff72c8 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 ea932b84396..42dee4da37b 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 744dbfc6e48..0b97d47691f 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)) && -- GitLab From 315806cb19f9d375dccbc2d60fa14e16afdcd5ac Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [PATCH 2130/2509] [MIPS] Malta: Cleanup organization of code into directories. Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 5 ++-- arch/mips/mips-boards/generic/Makefile | 29 ------------------- arch/mips/mips-boards/malta/Makefile | 27 ----------------- arch/mips/mti-malta/Makefile | 21 ++++++++++++++ .../generic/amon.c => mti-malta/malta-amon.c} | 0 .../cmdline.c => mti-malta/malta-cmdline.c} | 0 .../console.c => mti-malta/malta-console.c} | 0 .../display.c => mti-malta/malta-display.c} | 0 .../generic/init.c => mti-malta/malta-init.c} | 0 .../malta_int.c => mti-malta/malta-int.c} | 0 .../gdb_hook.c => mti-malta/malta-kgdb.c} | 0 .../memory.c => mti-malta/malta-memory.c} | 0 .../malta_mtd.c => mti-malta/malta-mtd.c} | 0 .../generic/pci.c => mti-malta/malta-pci.c} | 0 .../malta-platform.c} | 0 .../reset.c => mti-malta/malta-reset.c} | 0 .../malta_setup.c => mti-malta/malta-setup.c} | 0 .../malta_smtc.c => mti-malta/malta-smtc.c} | 0 .../generic/time.c => mti-malta/malta-time.c} | 0 .../cpu-feature-overrides.h | 0 .../asm-mips/{mach-mips => mach-malta}/irq.h | 0 .../kernel-entry-init.h | 0 .../{mach-mips => mach-malta}/mach-gt64120.h | 0 .../{mach-mips => mach-malta}/mc146818rtc.h | 0 .../asm-mips/{mach-mips => mach-malta}/war.h | 0 25 files changed, 23 insertions(+), 59 deletions(-) delete mode 100644 arch/mips/mips-boards/generic/Makefile delete mode 100644 arch/mips/mips-boards/malta/Makefile create mode 100644 arch/mips/mti-malta/Makefile rename arch/mips/{mips-boards/generic/amon.c => mti-malta/malta-amon.c} (100%) rename arch/mips/{mips-boards/generic/cmdline.c => mti-malta/malta-cmdline.c} (100%) rename arch/mips/{mips-boards/generic/console.c => mti-malta/malta-console.c} (100%) rename arch/mips/{mips-boards/generic/display.c => mti-malta/malta-display.c} (100%) rename arch/mips/{mips-boards/generic/init.c => mti-malta/malta-init.c} (100%) rename arch/mips/{mips-boards/malta/malta_int.c => mti-malta/malta-int.c} (100%) rename arch/mips/{mips-boards/generic/gdb_hook.c => mti-malta/malta-kgdb.c} (100%) rename arch/mips/{mips-boards/generic/memory.c => mti-malta/malta-memory.c} (100%) rename arch/mips/{mips-boards/malta/malta_mtd.c => mti-malta/malta-mtd.c} (100%) rename arch/mips/{mips-boards/generic/pci.c => mti-malta/malta-pci.c} (100%) rename arch/mips/{mips-boards/malta/malta_platform.c => mti-malta/malta-platform.c} (100%) rename arch/mips/{mips-boards/generic/reset.c => mti-malta/malta-reset.c} (100%) rename arch/mips/{mips-boards/malta/malta_setup.c => mti-malta/malta-setup.c} (100%) rename arch/mips/{mips-boards/malta/malta_smtc.c => mti-malta/malta-smtc.c} (100%) rename arch/mips/{mips-boards/generic/time.c => mti-malta/malta-time.c} (100%) rename include/asm-mips/{mach-mips => mach-malta}/cpu-feature-overrides.h (100%) rename include/asm-mips/{mach-mips => mach-malta}/irq.h (100%) rename include/asm-mips/{mach-mips => mach-malta}/kernel-entry-init.h (100%) rename include/asm-mips/{mach-mips => mach-malta}/mach-gt64120.h (100%) rename include/asm-mips/{mach-mips => mach-malta}/mc146818rtc.h (100%) rename include/asm-mips/{mach-mips => mach-malta}/war.h (100%) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ed8821ac8a8..36aa690484c 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 f7f87fc09d1..00000000000 --- 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/malta/Makefile b/arch/mips/mips-boards/malta/Makefile deleted file mode 100644 index db4ad654a6d..00000000000 --- 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/mti-malta/Makefile b/arch/mips/mti-malta/Makefile new file mode 100644 index 00000000000..f8064446e81 --- /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/mips-boards/generic/amon.c b/arch/mips/mti-malta/malta-amon.c similarity index 100% rename from arch/mips/mips-boards/generic/amon.c rename to arch/mips/mti-malta/malta-amon.c diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mti-malta/malta-cmdline.c similarity index 100% rename from arch/mips/mips-boards/generic/cmdline.c rename to arch/mips/mti-malta/malta-cmdline.c diff --git a/arch/mips/mips-boards/generic/console.c b/arch/mips/mti-malta/malta-console.c similarity index 100% rename from arch/mips/mips-boards/generic/console.c rename to arch/mips/mti-malta/malta-console.c diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mti-malta/malta-display.c similarity index 100% rename from arch/mips/mips-boards/generic/display.c rename to arch/mips/mti-malta/malta-display.c diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mti-malta/malta-init.c similarity index 100% rename from arch/mips/mips-boards/generic/init.c rename to arch/mips/mti-malta/malta-init.c diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mti-malta/malta-int.c similarity index 100% rename from arch/mips/mips-boards/malta/malta_int.c rename to arch/mips/mti-malta/malta-int.c diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mti-malta/malta-kgdb.c similarity index 100% rename from arch/mips/mips-boards/generic/gdb_hook.c rename to arch/mips/mti-malta/malta-kgdb.c diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mti-malta/malta-memory.c similarity index 100% rename from arch/mips/mips-boards/generic/memory.c rename to arch/mips/mti-malta/malta-memory.c diff --git a/arch/mips/mips-boards/malta/malta_mtd.c b/arch/mips/mti-malta/malta-mtd.c similarity index 100% rename from arch/mips/mips-boards/malta/malta_mtd.c rename to arch/mips/mti-malta/malta-mtd.c diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mti-malta/malta-pci.c similarity index 100% rename from arch/mips/mips-boards/generic/pci.c rename to arch/mips/mti-malta/malta-pci.c diff --git a/arch/mips/mips-boards/malta/malta_platform.c b/arch/mips/mti-malta/malta-platform.c similarity index 100% rename from arch/mips/mips-boards/malta/malta_platform.c rename to arch/mips/mti-malta/malta-platform.c diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mti-malta/malta-reset.c similarity index 100% rename from arch/mips/mips-boards/generic/reset.c rename to arch/mips/mti-malta/malta-reset.c diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mti-malta/malta-setup.c similarity index 100% rename from arch/mips/mips-boards/malta/malta_setup.c rename to arch/mips/mti-malta/malta-setup.c diff --git a/arch/mips/mips-boards/malta/malta_smtc.c b/arch/mips/mti-malta/malta-smtc.c similarity index 100% rename from arch/mips/mips-boards/malta/malta_smtc.c rename to arch/mips/mti-malta/malta-smtc.c diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mti-malta/malta-time.c similarity index 100% rename from arch/mips/mips-boards/generic/time.c rename to arch/mips/mti-malta/malta-time.c diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-malta/cpu-feature-overrides.h similarity index 100% rename from include/asm-mips/mach-mips/cpu-feature-overrides.h rename to include/asm-mips/mach-malta/cpu-feature-overrides.h diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-malta/irq.h similarity index 100% rename from include/asm-mips/mach-mips/irq.h rename to include/asm-mips/mach-malta/irq.h diff --git a/include/asm-mips/mach-mips/kernel-entry-init.h b/include/asm-mips/mach-malta/kernel-entry-init.h similarity index 100% rename from include/asm-mips/mach-mips/kernel-entry-init.h rename to include/asm-mips/mach-malta/kernel-entry-init.h diff --git a/include/asm-mips/mach-mips/mach-gt64120.h b/include/asm-mips/mach-malta/mach-gt64120.h similarity index 100% rename from include/asm-mips/mach-mips/mach-gt64120.h rename to include/asm-mips/mach-malta/mach-gt64120.h diff --git a/include/asm-mips/mach-mips/mc146818rtc.h b/include/asm-mips/mach-malta/mc146818rtc.h similarity index 100% rename from include/asm-mips/mach-mips/mc146818rtc.h rename to include/asm-mips/mach-malta/mc146818rtc.h diff --git a/include/asm-mips/mach-mips/war.h b/include/asm-mips/mach-malta/war.h similarity index 100% rename from include/asm-mips/mach-mips/war.h rename to include/asm-mips/mach-malta/war.h -- GitLab From 14476007c90005c8992b786c15a59cca31f53268 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 10 Jul 2008 01:02:08 +0900 Subject: [PATCH 2131/2509] [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 --- arch/mips/kernel/gpio_txx9.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c index b1436a85799..c6854d9df92 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; } -- GitLab From 22b1d707ffc99faebd86257ad19d5bb9fc624734 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:31:36 +0900 Subject: [PATCH 2132/2509] [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 --- arch/mips/Kconfig | 3 +- arch/mips/Makefile | 12 ++-- arch/mips/jmr3927/common/Makefile | 7 --- arch/mips/jmr3927/common/puts.c | 60 ------------------- arch/mips/pci/Makefile | 2 +- arch/mips/pci/fixup-jmr3927.c | 2 +- arch/mips/pci/fixup-rbtx4927.c | 2 +- .../pci/{fixup-tx4938.c => fixup-rbtx4938.c} | 2 +- arch/mips/pci/ops-tx3927.c | 2 +- arch/mips/pci/ops-tx4927.c | 2 +- arch/mips/pci/ops-tx4938.c | 2 +- arch/mips/pci/pci-jmr3927.c | 2 +- arch/mips/tx4927/Kconfig | 3 - arch/mips/tx4927/common/Makefile | 10 ---- arch/mips/tx4927/common/tx4927_dbgio.c | 43 ------------- arch/mips/tx4927/toshiba_rbtx4927/Makefile | 5 -- arch/mips/tx4938/common/Makefile | 8 --- arch/mips/{tx4938 => txx9}/Kconfig | 4 ++ arch/mips/txx9/generic/Makefile | 10 ++++ .../{tx4938/common => txx9/generic}/dbgio.c | 0 .../generic/irq_tx4927.c} | 3 +- .../irq.c => txx9/generic/irq_tx4938.c} | 2 +- .../generic/mem_tx4927.c} | 1 - .../prom.c => txx9/generic/mem_tx4938.c} | 0 .../common => txx9/generic}/smsc_fdc37m81x.c | 2 +- .../rbhma3100 => txx9/jmr3927}/Makefile | 4 +- .../rbhma3100 => txx9/jmr3927}/init.c | 2 +- .../{jmr3927/rbhma3100 => txx9/jmr3927}/irq.c | 2 +- .../rbhma3100 => txx9/jmr3927}/kgdb_io.c | 2 +- .../{jmr3927/common => txx9/jmr3927}/prom.c | 26 ++++++++ .../rbhma3100 => txx9/jmr3927}/setup.c | 2 +- arch/mips/txx9/rbtx4927/Makefile | 3 + .../rbtx4927/irq.c} | 4 +- .../rbtx4927/prom.c} | 2 +- .../rbtx4927/setup.c} | 4 +- .../rbtx4938}/Makefile | 4 -- .../toshiba_rbtx4938 => txx9/rbtx4938}/irq.c | 4 +- .../toshiba_rbtx4938 => txx9/rbtx4938}/prom.c | 4 +- .../rbtx4938}/setup.c | 6 +- .../rbtx4938}/spi_eeprom.c | 4 +- include/asm-mips/{jmr3927 => txx9}/jmr3927.h | 8 +-- .../toshiba_rbtx4927.h => txx9/rbtx4927.h} | 8 +-- include/asm-mips/{tx4938 => txx9}/rbtx4938.h | 9 ++- .../{tx4927 => txx9}/smsc_fdc37m81x.h | 2 - include/asm-mips/{tx4938 => txx9}/spi.h | 7 +-- include/asm-mips/{jmr3927 => txx9}/tx3927.h | 8 +-- include/asm-mips/{tx4927 => txx9}/tx4927.h | 6 +- include/asm-mips/{tx4938 => txx9}/tx4938.h | 5 +- include/asm-mips/{jmr3927 => txx9}/txx927.h | 6 +- 49 files changed, 104 insertions(+), 217 deletions(-) delete mode 100644 arch/mips/jmr3927/common/Makefile delete mode 100644 arch/mips/jmr3927/common/puts.c rename arch/mips/pci/{fixup-tx4938.c => fixup-rbtx4938.c} (98%) delete mode 100644 arch/mips/tx4927/Kconfig delete mode 100644 arch/mips/tx4927/common/Makefile delete mode 100644 arch/mips/tx4927/common/tx4927_dbgio.c delete mode 100644 arch/mips/tx4927/toshiba_rbtx4927/Makefile delete mode 100644 arch/mips/tx4938/common/Makefile rename arch/mips/{tx4938 => txx9}/Kconfig (86%) create mode 100644 arch/mips/txx9/generic/Makefile rename arch/mips/{tx4938/common => txx9/generic}/dbgio.c (100%) rename arch/mips/{tx4927/common/tx4927_irq.c => txx9/generic/irq_tx4927.c} (96%) rename arch/mips/{tx4938/common/irq.c => txx9/generic/irq_tx4938.c} (97%) rename arch/mips/{tx4927/common/tx4927_prom.c => txx9/generic/mem_tx4927.c} (99%) rename arch/mips/{tx4938/common/prom.c => txx9/generic/mem_tx4938.c} (100%) rename arch/mips/{tx4927/common => txx9/generic}/smsc_fdc37m81x.c (99%) rename arch/mips/{jmr3927/rbhma3100 => txx9/jmr3927}/Makefile (50%) rename arch/mips/{jmr3927/rbhma3100 => txx9/jmr3927}/init.c (98%) rename arch/mips/{jmr3927/rbhma3100 => txx9/jmr3927}/irq.c (99%) rename arch/mips/{jmr3927/rbhma3100 => txx9/jmr3927}/kgdb_io.c (98%) rename arch/mips/{jmr3927/common => txx9/jmr3927}/prom.c (84%) rename arch/mips/{jmr3927/rbhma3100 => txx9/jmr3927}/setup.c (99%) create mode 100644 arch/mips/txx9/rbtx4927/Makefile rename arch/mips/{tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c => txx9/rbtx4927/irq.c} (98%) rename arch/mips/{tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c => txx9/rbtx4927/prom.c} (98%) rename arch/mips/{tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c => txx9/rbtx4927/setup.c} (99%) rename arch/mips/{tx4938/toshiba_rbtx4938 => txx9/rbtx4938}/Makefile (51%) rename arch/mips/{tx4938/toshiba_rbtx4938 => txx9/rbtx4938}/irq.c (97%) rename arch/mips/{tx4938/toshiba_rbtx4938 => txx9/rbtx4938}/prom.c (94%) rename arch/mips/{tx4938/toshiba_rbtx4938 => txx9/rbtx4938}/setup.c (99%) rename arch/mips/{tx4938/toshiba_rbtx4938 => txx9/rbtx4938}/spi_eeprom.c (96%) rename include/asm-mips/{jmr3927 => txx9}/jmr3927.h (98%) rename include/asm-mips/{tx4927/toshiba_rbtx4927.h => txx9/rbtx4927.h} (92%) rename include/asm-mips/{tx4938 => txx9}/rbtx4938.h (97%) rename include/asm-mips/{tx4927 => txx9}/smsc_fdc37m81x.h (97%) rename include/asm-mips/{tx4938 => txx9}/spi.h (77%) rename include/asm-mips/{jmr3927 => txx9}/tx3927.h (98%) rename include/asm-mips/{tx4927 => txx9}/tx4927.h (99%) rename include/asm-mips/{tx4938 => txx9}/tx4938.h (99%) rename include/asm-mips/{jmr3927 => txx9}/txx927.h (97%) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a0381427ec5..3202960f759 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 36aa690484c..8e1e49c5186 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 8fd4fcccf10..00000000000 --- 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/puts.c b/arch/mips/jmr3927/common/puts.c deleted file mode 100644 index c611ab49788..00000000000 --- 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/pci/Makefile b/arch/mips/pci/Makefile index 80fa5abb25d..4608e43de28 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 e974394be7b..41dcd6a3aae 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 2d234ca017d..26013badfe1 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-tx4938.c b/arch/mips/pci/fixup-rbtx4938.c similarity index 98% rename from arch/mips/pci/fixup-tx4938.c rename to arch/mips/pci/fixup-rbtx4938.c index f2ba06ee0c1..64d4510c026 100644 --- a/arch/mips/pci/fixup-tx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -14,7 +14,7 @@ #include #include -#include +#include extern struct pci_controller tx4938_pci_controller[]; diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index aa698bd0d5e..5d398f69468 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 1bbafeb4a77..54730eee451 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 a450c406203..34494b82cb2 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 cb84f4e8cca..7fb6bd71901 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 5fbbe12e0fc..00000000000 --- 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 a7fe76a6496..00000000000 --- 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/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c deleted file mode 100644 index ea1ff23f4b7..00000000000 --- 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/toshiba_rbtx4927/Makefile b/arch/mips/tx4927/toshiba_rbtx4927/Makefile deleted file mode 100644 index 13f96725d77..00000000000 --- 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/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile deleted file mode 100644 index 56aa1ed1ee0..00000000000 --- 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/Kconfig b/arch/mips/txx9/Kconfig similarity index 86% rename from arch/mips/tx4938/Kconfig rename to arch/mips/txx9/Kconfig index d90e9cd8513..98d103402b1 100644 --- a/arch/mips/tx4938/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -1,3 +1,7 @@ +config TOSHIBA_FPCIB0 + bool "FPCIB0 Backplane Support" + depends on TOSHIBA_RBTX4927 + if TOSHIBA_RBTX4938 comment "Multiplex Pin Select" diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile new file mode 100644 index 00000000000..8cb4a7e8147 --- /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/tx4938/common/dbgio.c b/arch/mips/txx9/generic/dbgio.c similarity index 100% rename from arch/mips/tx4938/common/dbgio.c rename to arch/mips/txx9/generic/dbgio.c diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/txx9/generic/irq_tx4927.c similarity index 96% rename from arch/mips/tx4927/common/tx4927_irq.c rename to arch/mips/txx9/generic/irq_tx4927.c index 0aabd57fdad..685ecc2ed55 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -27,9 +27,8 @@ #include #include #include -#include #ifdef CONFIG_TOSHIBA_RBTX4927 -#include +#include #endif void __init tx4927_irq_init(void) diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/txx9/generic/irq_tx4938.c similarity index 97% rename from arch/mips/tx4938/common/irq.c rename to arch/mips/txx9/generic/irq_tx4938.c index c059b899d12..0886d913881 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include void __init tx4938_irq_init(void) diff --git a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/txx9/generic/mem_tx4927.c similarity index 99% rename from arch/mips/tx4927/common/tx4927_prom.c rename to arch/mips/txx9/generic/mem_tx4927.c index cc2aa9d63e8..12dfc377bf2 100644 --- a/arch/mips/tx4927/common/tx4927_prom.c +++ b/arch/mips/txx9/generic/mem_tx4927.c @@ -32,7 +32,6 @@ #include #include #include -#include static unsigned int __init tx4927_process_sdccr(unsigned long addr) { diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/txx9/generic/mem_tx4938.c similarity index 100% rename from arch/mips/tx4938/common/prom.c rename to arch/mips/txx9/generic/mem_tx4938.c diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c similarity index 99% rename from arch/mips/tx4927/common/smsc_fdc37m81x.c rename to arch/mips/txx9/generic/smsc_fdc37m81x.c index 33f517bc9a0..69e487467fa 100644 --- a/arch/mips/tx4927/common/smsc_fdc37m81x.c +++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #define DEBUG diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/txx9/jmr3927/Makefile similarity index 50% rename from arch/mips/jmr3927/rbhma3100/Makefile rename to arch/mips/txx9/jmr3927/Makefile index d86e30dca8f..5f83ea37522 100644 --- a/arch/mips/jmr3927/rbhma3100/Makefile +++ b/arch/mips/txx9/jmr3927/Makefile @@ -2,7 +2,7 @@ # Makefile for TOSHIBA JMR-TX3927 board # -obj-y += init.o irq.o setup.o -obj-$(CONFIG_KGDB) += kgdb_io.o +obj-y += prom.o 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/txx9/jmr3927/init.c similarity index 98% rename from arch/mips/jmr3927/rbhma3100/init.c rename to arch/mips/txx9/jmr3927/init.c index 700b9cf8eb9..1bbb5343baf 100644 --- a/arch/mips/jmr3927/rbhma3100/init.c +++ b/arch/mips/txx9/jmr3927/init.c @@ -29,7 +29,7 @@ */ #include #include -#include +#include extern void __init prom_init_cmdline(void); diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/txx9/jmr3927/irq.c similarity index 99% rename from arch/mips/jmr3927/rbhma3100/irq.c rename to arch/mips/txx9/jmr3927/irq.c index 3a47e8ce119..85e1daf15c7 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -39,7 +39,7 @@ #include #include -#include +#include #if JMR3927_IRQ_END > NR_IRQS #error JMR3927_IRQ_END > NR_IRQS diff --git a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/txx9/jmr3927/kgdb_io.c similarity index 98% rename from arch/mips/jmr3927/rbhma3100/kgdb_io.c rename to arch/mips/txx9/jmr3927/kgdb_io.c index 342579cfdc0..5bd757e56f7 100644 --- a/arch/mips/jmr3927/rbhma3100/kgdb_io.c +++ b/arch/mips/txx9/jmr3927/kgdb_io.c @@ -31,7 +31,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #define TIMEOUT 0xffffff diff --git a/arch/mips/jmr3927/common/prom.c b/arch/mips/txx9/jmr3927/prom.c similarity index 84% rename from arch/mips/jmr3927/common/prom.c rename to arch/mips/txx9/jmr3927/prom.c index 5398813e50e..8bc1049b622 100644 --- a/arch/mips/jmr3927/common/prom.c +++ b/arch/mips/txx9/jmr3927/prom.c @@ -40,6 +40,7 @@ #include #include +#include char * __init prom_getcmdline(void) { @@ -70,3 +71,28 @@ void __init prom_init_cmdline(void) 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/jmr3927/rbhma3100/setup.c b/arch/mips/txx9/jmr3927/setup.c similarity index 99% rename from arch/mips/jmr3927/rbhma3100/setup.c rename to arch/mips/txx9/jmr3927/setup.c index f39c444e42d..41e0f3b3af2 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include extern void puts(const char *cp); diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile new file mode 100644 index 00000000000..f3e1f597b4f --- /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/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/txx9/rbtx4927/irq.c similarity index 98% rename from arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c rename to arch/mips/txx9/rbtx4927/irq.c index c18901a75cc..936e50e91d9 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c - * * Toshiba RBTX4927 specific interrupt handlers * * Author: MontaVista Software, Inc. @@ -116,7 +114,7 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #ifdef CONFIG_TOSHIBA_FPCIB0 #include #endif -#include +#include #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/txx9/rbtx4927/prom.c similarity index 98% rename from arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c rename to arch/mips/txx9/rbtx4927/prom.c index fdbad4bc602..0020bbee838 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -34,7 +34,7 @@ #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/txx9/rbtx4927/setup.c similarity index 99% rename from arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c rename to arch/mips/txx9/rbtx4927/setup.c index 185f303c0e2..df1b6e99b66 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -59,9 +59,9 @@ #include #include #ifdef CONFIG_TOSHIBA_FPCIB0 -#include +#include #endif -#include +#include #ifdef CONFIG_SERIAL_TXX9 #include #endif diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile similarity index 51% rename from arch/mips/tx4938/toshiba_rbtx4938/Makefile rename to arch/mips/txx9/rbtx4938/Makefile index 2316dd7dd1b..9dcc52ae5b9 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile +++ b/arch/mips/txx9/rbtx4938/Makefile @@ -1,7 +1,3 @@ -# -# 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/txx9/rbtx4938/irq.c similarity index 97% rename from arch/mips/tx4938/toshiba_rbtx4938/irq.c rename to arch/mips/txx9/rbtx4938/irq.c index 4d6a8dc46c7..f4984820251 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c - * * Toshiba RBTX4938 specific interrupt handlers * Copyright (C) 2000-2001 Toshiba Corporation * @@ -68,7 +66,7 @@ IRQ Device */ #include #include -#include +#include static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c similarity index 94% rename from arch/mips/tx4938/toshiba_rbtx4938/prom.c rename to arch/mips/txx9/rbtx4938/prom.c index 1644bffa501..134fcc2dc7d 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/prom.c +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c - * * rbtx4938 specific prom routines * Copyright (C) 2000-2001 Toshiba Corporation * @@ -19,7 +17,7 @@ #include #include -#include +#include void __init prom_init_cmdline(void) { diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c similarity index 99% rename from arch/mips/tx4938/toshiba_rbtx4938/setup.c rename to arch/mips/txx9/rbtx4938/setup.c index 3a3659e8633..bbd572c9675 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -1,6 +1,4 @@ /* - * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c - * * Setup pointers to hardware-dependent routines. * Copyright (C) 2000-2001 Toshiba Corporation * @@ -28,12 +26,12 @@ #include #include #include -#include +#include #ifdef CONFIG_SERIAL_TXX9 #include #endif #include -#include +#include #include extern char * __init prom_getcmdline(void); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/txx9/rbtx4938/spi_eeprom.c similarity index 96% rename from arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c rename to arch/mips/txx9/rbtx4938/spi_eeprom.c index 4d6b4ade5e8..a7ea8b041c1 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c +++ b/arch/mips/txx9/rbtx4938/spi_eeprom.c @@ -1,5 +1,5 @@ /* - * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c + * spi_eeprom.c * Copyright (C) 2000-2001 Toshiba Corporation * * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the @@ -13,7 +13,7 @@ #include #include #include -#include +#include #define AT250X0_PAGE_SIZE 8 diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/txx9/jmr3927.h similarity index 98% rename from include/asm-mips/jmr3927/jmr3927.h rename to include/asm-mips/txx9/jmr3927.h index a162268f17d..29e54981a86 100644 --- a/include/asm-mips/jmr3927/jmr3927.h +++ b/include/asm-mips/txx9/jmr3927.h @@ -7,10 +7,10 @@ * * Copyright (C) 2000-2001 Toshiba Corporation */ -#ifndef __ASM_TX3927_JMR3927_H -#define __ASM_TX3927_JMR3927_H +#ifndef __ASM_TXX9_JMR3927_H +#define __ASM_TXX9_JMR3927_H -#include +#include #include #include #include @@ -174,4 +174,4 @@ * INT[3:0] */ -#endif /* __ASM_TX3927_JMR3927_H */ +#endif /* __ASM_TXX9_JMR3927_H */ diff --git a/include/asm-mips/tx4927/toshiba_rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h similarity index 92% rename from include/asm-mips/tx4927/toshiba_rbtx4927.h rename to include/asm-mips/txx9/rbtx4927.h index d6b32acd6b7..5531342bcc0 100644 --- a/include/asm-mips/tx4927/toshiba_rbtx4927.h +++ b/include/asm-mips/txx9/rbtx4927.h @@ -24,10 +24,10 @@ * 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 +#ifndef __ASM_TXX9_RBTX4927_H +#define __ASM_TXX9_RBTX4927_H -#include +#include #ifdef CONFIG_PCI #define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO @@ -46,4 +46,4 @@ int toshiba_rbtx4927_irq_nested(int sw_irq); -#endif /* __ASM_TX4927_TOSHIBA_RBTX4927_H */ +#endif /* __ASM_TXX9_RBTX4927_H */ diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/txx9/rbtx4938.h similarity index 97% rename from include/asm-mips/tx4938/rbtx4938.h rename to include/asm-mips/txx9/rbtx4938.h index dfed7beb533..8450f735d05 100644 --- a/include/asm-mips/tx4938/rbtx4938.h +++ b/include/asm-mips/txx9/rbtx4938.h @@ -1,5 +1,4 @@ /* - * linux/include/asm-mips/tx4938/rbtx4938.h * Definitions for TX4937/TX4938 * * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the @@ -9,12 +8,12 @@ * * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ -#ifndef __ASM_TX_BOARDS_RBTX4938_H -#define __ASM_TX_BOARDS_RBTX4938_H +#ifndef __ASM_TXX9_RBTX4938_H +#define __ASM_TXX9_RBTX4938_H #include -#include #include +#include /* CS */ #define RBTX4938_CE0 0x1c000000 /* 64M */ @@ -165,4 +164,4 @@ #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 */ +#endif /* __ASM_TXX9_RBTX4938_H */ diff --git a/include/asm-mips/tx4927/smsc_fdc37m81x.h b/include/asm-mips/txx9/smsc_fdc37m81x.h similarity index 97% rename from include/asm-mips/tx4927/smsc_fdc37m81x.h rename to include/asm-mips/txx9/smsc_fdc37m81x.h index 5d93bab5125..9375e4fc228 100644 --- a/include/asm-mips/tx4927/smsc_fdc37m81x.h +++ b/include/asm-mips/txx9/smsc_fdc37m81x.h @@ -1,6 +1,4 @@ /* - * linux/include/asm-mips/tx4927/smsc_fdc37m81x.h - * * Interface for smsc fdc48m81x Super IO chip * * Author: MontaVista Software, Inc. source@mvista.com diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/txx9/spi.h similarity index 77% rename from include/asm-mips/tx4938/spi.h rename to include/asm-mips/txx9/spi.h index 6a60c83e152..ddfb2a0dc43 100644 --- a/include/asm-mips/tx4938/spi.h +++ b/include/asm-mips/txx9/spi.h @@ -1,5 +1,4 @@ /* - * linux/include/asm-mips/tx4938/spi.h * Definitions for TX4937/TX4938 SPI * * Copyright (C) 2000-2001 Toshiba Corporation @@ -11,10 +10,10 @@ * * 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 +#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_TX_BOARDS_TX4938_SPI_H */ +#endif /* __ASM_TXX9_SPI_H */ diff --git a/include/asm-mips/jmr3927/tx3927.h b/include/asm-mips/txx9/tx3927.h similarity index 98% rename from include/asm-mips/jmr3927/tx3927.h rename to include/asm-mips/txx9/tx3927.h index fb580333c10..63b62d6061f 100644 --- a/include/asm-mips/jmr3927/tx3927.h +++ b/include/asm-mips/txx9/tx3927.h @@ -5,10 +5,10 @@ * * Copyright (C) 2000 Toshiba Corporation */ -#ifndef __ASM_TX3927_H -#define __ASM_TX3927_H +#ifndef __ASM_TXX9_TX3927_H +#define __ASM_TXX9_TX3927_H -#include +#include #define TX3927_SDRAMC_REG 0xfffe8000 #define TX3927_ROMC_REG 0xfffe9000 @@ -316,4 +316,4 @@ 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) -#endif /* __ASM_TX3927_H */ +#endif /* __ASM_TXX9_TX3927_H */ diff --git a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/txx9/tx4927.h similarity index 99% rename from include/asm-mips/tx4927/tx4927.h rename to include/asm-mips/txx9/tx4927.h index 1d4816f3266..f21a7b1831e 100644 --- a/include/asm-mips/tx4927/tx4927.h +++ b/include/asm-mips/txx9/tx4927.h @@ -24,8 +24,8 @@ * 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 +#ifndef __ASM_TXX9_TX4927_H +#define __ASM_TXX9_TX4927_H #include @@ -277,4 +277,4 @@ struct tx4927_pcic_reg { #endif /* _LANGUAGE_ASSEMBLY */ -#endif /* __ASM_TX4927_TX4927_H */ +#endif /* __ASM_TXX9_TX4927_H */ diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/txx9/tx4938.h similarity index 99% rename from include/asm-mips/tx4938/tx4938.h rename to include/asm-mips/txx9/tx4938.h index e8807f5c61e..7f9cfef1c6d 100644 --- a/include/asm-mips/tx4938/tx4938.h +++ b/include/asm-mips/txx9/tx4938.h @@ -1,5 +1,4 @@ /* - * linux/include/asm-mips/tx4938/tx4938.h * Definitions for TX4937/TX4938 * Copyright (C) 2000-2001 Toshiba Corporation * @@ -10,8 +9,8 @@ * * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ -#ifndef __ASM_TX_BOARDS_TX4938_H -#define __ASM_TX_BOARDS_TX4938_H +#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) diff --git a/include/asm-mips/jmr3927/txx927.h b/include/asm-mips/txx9/txx927.h similarity index 97% rename from include/asm-mips/jmr3927/txx927.h rename to include/asm-mips/txx9/txx927.h index 25dcf2feb09..97dd7ad1a89 100644 --- a/include/asm-mips/jmr3927/txx927.h +++ b/include/asm-mips/txx9/txx927.h @@ -7,8 +7,8 @@ * * Copyright (C) 2000 Toshiba Corporation */ -#ifndef __ASM_TXX927_H -#define __ASM_TXX927_H +#ifndef __ASM_TXX9_TXX927_H +#define __ASM_TXX9_TXX927_H struct txx927_sio_reg { volatile unsigned long lcr; @@ -118,4 +118,4 @@ struct txx927_sio_reg { * PIO */ -#endif /* __ASM_TXX927_H */ +#endif /* __ASM_TXX9_TXX927_H */ -- GitLab From 89d63fe179520b11f54de1f26755b7444c79e73a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:33:08 +0900 Subject: [PATCH 2133/2509] [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 --- arch/mips/Kconfig | 3 +- arch/mips/pci/Makefile | 8 +- arch/mips/pci/fixup-jmr3927.c | 25 +- arch/mips/pci/fixup-rbtx4927.c | 112 ++--- arch/mips/pci/fixup-rbtx4938.c | 52 +-- arch/mips/pci/ops-tx3927.c | 87 +++- arch/mips/pci/ops-tx4927.c | 514 +++++++++++++++------- arch/mips/pci/ops-tx4938.c | 214 --------- arch/mips/pci/pci-jmr3927.c | 58 --- arch/mips/pci/pci-tx4927.c | 83 ++++ arch/mips/pci/pci-tx4938.c | 134 ++++++ arch/mips/txx9/Kconfig | 11 +- arch/mips/txx9/generic/Makefile | 2 + arch/mips/txx9/generic/pci.c | 377 ++++++++++++++++ arch/mips/txx9/generic/setup.c | 51 +++ arch/mips/txx9/jmr3927/irq.c | 2 + arch/mips/txx9/jmr3927/setup.c | 108 ++--- arch/mips/txx9/rbtx4927/irq.c | 20 +- arch/mips/txx9/rbtx4927/setup.c | 499 ++++++--------------- arch/mips/txx9/rbtx4938/setup.c | 667 +++++------------------------ include/asm-mips/txx9/generic.h | 23 + include/asm-mips/txx9/pci.h | 36 ++ include/asm-mips/txx9/rbtx4927.h | 29 +- include/asm-mips/txx9/tx3927.h | 4 + include/asm-mips/txx9/tx4927.h | 318 ++++++-------- include/asm-mips/txx9/tx4927pcic.h | 199 +++++++++ include/asm-mips/txx9/tx4938.h | 226 ++-------- 27 files changed, 1851 insertions(+), 2011 deletions(-) delete mode 100644 arch/mips/pci/ops-tx4938.c delete mode 100644 arch/mips/pci/pci-jmr3927.c create mode 100644 arch/mips/pci/pci-tx4927.c create mode 100644 arch/mips/pci/pci-tx4938.c create mode 100644 arch/mips/txx9/generic/pci.c create mode 100644 arch/mips/txx9/generic/setup.c create mode 100644 include/asm-mips/txx9/generic.h create mode 100644 include/asm-mips/txx9/pci.h create mode 100644 include/asm-mips/txx9/tx4927pcic.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3202960f759..2ea6fff8881 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 4608e43de28..908764878ac 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 41dcd6a3aae..d5edaf21e08 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 26013badfe1..abab4852d15 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 64d4510c026..39c99583038 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 5d398f69468..8a17a39e5bf 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 54730eee451..c6b49bccd27 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 34494b82cb2..00000000000 --- 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 7fb6bd71901..00000000000 --- 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 00000000000..27e86a09dd4 --- /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 00000000000..e5375511c2b --- /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 98d103402b1..b8cdb192543 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 8cb4a7e8147..b80b6e07228 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 00000000000..8173faab99b --- /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 00000000000..46a63117775 --- /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 85e1daf15c7..b97d22e15da 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 41e0f3b3af2..baa8c8db9a9 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 936e50e91d9..bef1447aeed 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 df1b6e99b66..86b870abc31 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 bbd572c9675..144d2cada82 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 00000000000..2ff6c200220 --- /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 00000000000..d89a45091e2 --- /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 5531342bcc0..5b6f488b1b3 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 63b62d6061f..ca414c7624e 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 f21a7b1831e..c0382fd2ae7 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 00000000000..d61c3d09c4a --- /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 7f9cfef1c6d..0bb891993b0 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 -- GitLab From 766891565bdaf605ea4aebe3e75de77e848254d0 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:33:21 +0900 Subject: [PATCH 2134/2509] [MIPS] TXx9: Update defconfigs Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/configs/jmr3927_defconfig | 180 +++++++++++++++-------- arch/mips/configs/rbhma4200_defconfig | 153 ++++++++++++-------- arch/mips/configs/rbhma4500_defconfig | 196 +++++++++++++++++--------- 3 files changed, 340 insertions(+), 189 deletions(-) diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 92000a3a871..ab16e67ff08 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,19 +221,18 @@ 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 # @@ -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 @@ -492,30 +550,47 @@ CONFIG_TXX9_WDT=y # 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 -# 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 f89482a2aa6..e0af6a9f9f0 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,19 +232,18 @@ 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 # @@ -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 @@ -459,30 +492,47 @@ CONFIG_TXX9_WDT=m # 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 -# 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 70cf6976167..50aa1b64136 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,19 +240,18 @@ 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 # @@ -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 @@ -489,30 +554,47 @@ CONFIG_TXX9_WDT=m # 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 -# 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 -- GitLab From edcaf1a6a77315562e9781245cc8e028c9a921dc Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 23:27:54 +0900 Subject: [PATCH 2135/2509] [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 --- arch/mips/Kconfig | 67 +---------- arch/mips/Makefile | 21 ++-- arch/mips/pci/Makefile | 9 +- arch/mips/pci/fixup-jmr3927.c | 8 +- arch/mips/pci/fixup-rbtx4927.c | 8 +- arch/mips/pci/fixup-rbtx4938.c | 11 +- arch/mips/txx9/Kconfig | 82 +++++++++++++- arch/mips/txx9/generic/Makefile | 4 +- arch/mips/txx9/generic/irq_tx4927.c | 33 +----- arch/mips/txx9/generic/irq_tx4938.c | 31 +---- arch/mips/txx9/generic/pci.c | 11 ++ arch/mips/txx9/generic/setup.c | 169 ++++++++++++++++++++++++++++ arch/mips/txx9/jmr3927/Makefile | 2 +- arch/mips/txx9/jmr3927/init.c | 57 ---------- arch/mips/txx9/jmr3927/irq.c | 45 ++++---- arch/mips/txx9/jmr3927/prom.c | 46 ++------ arch/mips/txx9/jmr3927/setup.c | 54 ++++----- arch/mips/txx9/rbtx4927/irq.c | 57 +++++----- arch/mips/txx9/rbtx4927/prom.c | 52 +-------- arch/mips/txx9/rbtx4927/setup.c | 78 ++++++------- arch/mips/txx9/rbtx4938/irq.c | 48 ++++---- arch/mips/txx9/rbtx4938/prom.c | 49 +------- arch/mips/txx9/rbtx4938/setup.c | 64 ++++------- include/asm-mips/txx9/generic.h | 18 +++ include/asm-mips/txx9/jmr3927.h | 5 + include/asm-mips/txx9/rbtx4927.h | 13 ++- include/asm-mips/txx9/rbtx4938.h | 36 ++---- include/asm-mips/txx9/tx4927.h | 19 +--- include/asm-mips/txx9/tx4938.h | 8 +- 29 files changed, 520 insertions(+), 585 deletions(-) delete mode 100644 arch/mips/txx9/jmr3927/init.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2ea6fff8881..72baa1a70fc 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 8e1e49c5186..d319cd62413 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -550,30 +550,31 @@ load-$(CONFIG_SNI_RM) += 0xffffffff80030000 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 908764878ac..875b643438c 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 d5edaf21e08..0f1069527cb 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 abab4852d15..321db265829 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 39c99583038..a80579af609 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 b8cdb192543..b92a134ef12 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 b80b6e07228..668fdaad644 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 685ecc2ed55..6377bd8a905 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 0886d913881..5fc86c9c9d2 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 8173faab99b..0b92d8c1320 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 46a63117775..66ff74f80c6 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 5f83ea37522..ba292c94566 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 1bbb5343baf..00000000000 --- 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 b97d22e15da..070c9a115e5 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 8bc1049b622..2cadb423fac 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 baa8c8db9a9..128a4ae3e72 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 bef1447aeed..70f13211bc2 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 0020bbee838..942e627d2dc 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 86b870abc31..c3566c39c26 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 f4984820251..3971a061657 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 134fcc2dc7d..fbb37458ddb 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 144d2cada82..8306ba333dd 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 2ff6c200220..6cd147764f1 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 29e54981a86..d6eb1b6a54e 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 5b6f488b1b3..bf194589216 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 8450f735d05..2f5d5e705a4 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 c0382fd2ae7..46d60afc038 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 0bb891993b0..12de68a4c10 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 -- GitLab From bf744d417ff2fe1e8e386c7ad06e79c34a078642 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 23:28:04 +0900 Subject: [PATCH 2136/2509] [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 --- arch/mips/configs/jmr3927_defconfig | 10 +- arch/mips/configs/rbhma4200_defconfig | 698 ------------------ ...rbhma4500_defconfig => rbtx49xx_defconfig} | 14 +- 3 files changed, 14 insertions(+), 708 deletions(-) delete mode 100644 arch/mips/configs/rbhma4200_defconfig rename arch/mips/configs/{rbhma4500_defconfig => rbtx49xx_defconfig} (98%) diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index ab16e67ff08..9d5bd2a0af3 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 e0af6a9f9f0..00000000000 --- 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/rbtx49xx_defconfig similarity index 98% rename from arch/mips/configs/rbhma4500_defconfig rename to arch/mips/configs/rbtx49xx_defconfig index 50aa1b64136..e42aed5a38b 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.26-rc9 -# Thu Jul 10 23:53:27 2008 +# Fri Jul 11 23:03:21 2008 # CONFIG_MIPS=y @@ -37,10 +37,13 @@ CONFIG_MIPS=y # 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_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 @@ -106,6 +109,7 @@ CONFIG_CPU_TX49XX=y # 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 @@ -634,7 +638,7 @@ CONFIG_RTC_DRV_RS5C348=y # 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_DS1742=y # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T59 is not set -- GitLab From 5b438c44082d9f09fed10f3621fe8d5c93d3676d Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 10 Jul 2008 20:29:55 +0200 Subject: [PATCH 2137/2509] [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 --- arch/mips/Kconfig | 5 +++++ arch/mips/sgi-ip22/ip22-platform.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 72baa1a70fc..d23204e29e1 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 28ffec8e5d1..d93d07a8c31 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); -- GitLab From 9ecb1ff1b295a515b21d0ac83d8bd39b07335aab Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:39:14 +0900 Subject: [PATCH 2138/2509] [MIPS] replace inline assembler to cpu_wait() Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/gt64120/wrppmc/reset.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c index c355cff38f6..e66c87164a0 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(); } } -- GitLab From 3f16654f36723f5ef1ca38c4e2078ca377a0f86f Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:39:18 +0900 Subject: [PATCH 2139/2509] [MIPS] remove wrppmc_machine_power_off() It can be replace wrppmc_machine_halt(). Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/gt64120/wrppmc/reset.c | 5 ----- arch/mips/gt64120/wrppmc/setup.c | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c index e66c87164a0..cc5474b24f0 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 728ef6a80ed..ca65c84031a 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 -- GitLab From efff4ae259b8f750ea426d3084007f85c0a15a85 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:45:21 +0900 Subject: [PATCH 2140/2509] [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 --- arch/mips/Makefile | 6 - arch/mips/pci/Makefile | 1 - arch/mips/pci/fixup-vr4133.c | 194 ---------------- arch/mips/vr41xx/Kconfig | 17 -- arch/mips/vr41xx/nec-cmbvr4133/Makefile | 8 - arch/mips/vr41xx/nec-cmbvr4133/init.c | 65 ------ arch/mips/vr41xx/nec-cmbvr4133/irq.c | 46 ---- arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c | 249 --------------------- arch/mips/vr41xx/nec-cmbvr4133/setup.c | 89 -------- include/asm-mips/mach-vr41xx/irq.h | 3 - include/asm-mips/vr41xx/cmbvr4133.h | 56 ----- 11 files changed, 734 deletions(-) delete mode 100644 arch/mips/pci/fixup-vr4133.c delete mode 100644 arch/mips/vr41xx/nec-cmbvr4133/Makefile delete mode 100644 arch/mips/vr41xx/nec-cmbvr4133/init.c delete mode 100644 arch/mips/vr41xx/nec-cmbvr4133/irq.c delete mode 100644 arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c delete mode 100644 arch/mips/vr41xx/nec-cmbvr4133/setup.c delete mode 100644 include/asm-mips/vr41xx/cmbvr4133.h diff --git a/arch/mips/Makefile b/arch/mips/Makefile index d319cd62413..c4a3098a58c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -354,12 +354,6 @@ load-$(CONFIG_LASAT) += 0xffffffff80000000 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) # diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 875b643438c..57e34cafa49 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 34e651bd2b5..00000000000 --- 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 559acc09c81..c1be6b37fb2 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 5835cae54ac..00000000000 --- 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 7c5e18ee223..00000000000 --- 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 7d2d076b0f5..00000000000 --- 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 1341f3287d0..00000000000 --- 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 7723d2011b0..00000000000 --- 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 84881229605..862058d3f81 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 42300037d59..00000000000 --- 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 */ -- GitLab From b03d7b18fd783f39e31560d568e7db954f3080af Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 11 Jul 2008 23:03:03 +0200 Subject: [PATCH 2141/2509] [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 --- arch/mips/sgi-ip22/ip22-platform.c | 11 +++++++ arch/mips/sgi-ip22/ip22-reset.c | 51 ++---------------------------- 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index d93d07a8c31..fc6df96305e 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 a435b31cf03..4ad5c3393fd 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; } -- GitLab From 7a1fdf1946b641f7c2866b3386414657eeb88084 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 19:51:55 +0900 Subject: [PATCH 2142/2509] [MIPS] txx9_board_vec set directly without mips_machtype Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 66ff74f80c6..517828e1ec9 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) -- GitLab From a00fb6694f15b3bccf105f34f10bbcb6b47af67c Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 19:54:08 +0900 Subject: [PATCH 2143/2509] [MIPS] txx9_cpu_clock setup move to rbtx4927_time_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/rbtx4927/setup.c | 98 ++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index c3566c39c26..bba6ef9db06 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, -- GitLab From a38c47519832f22659244fd8437722b7aaa67f9a Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:01:04 +0900 Subject: [PATCH 2144/2509] [MIPS] separate rbtx4927_arch_init() and rbtx4937_arch_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/rbtx4927/setup.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index bba6ef9db06..b4c4178607c 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 -- GitLab From b6c4053610f04011bc0ecbc5a0417afe169b2693 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:02:13 +0900 Subject: [PATCH 2145/2509] [MIPS] separate rbtx4927_time_init() and rbtx4937_time_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/rbtx4927/setup.c | 78 +++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index b4c4178607c..adc91c0bbb9 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 -- GitLab From 6e68665e51b9937b132a990b9ae7f04118e64688 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:04:18 +0900 Subject: [PATCH 2146/2509] [MIPS] remove machtype for group Toshiba Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/jmr3927/setup.c | 1 - arch/mips/txx9/rbtx4927/setup.c | 2 -- arch/mips/txx9/rbtx4938/setup.c | 1 - include/asm-mips/bootinfo.h | 11 ----------- include/asm-mips/txx9/generic.h | 1 - 5 files changed, 16 deletions(-) diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 128a4ae3e72..43a8dad22ef 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 adc91c0bbb9..aba11f376a5 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 8306ba333dd..2ef71adea82 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 e031bdff992..c70848d4f63 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -61,17 +61,6 @@ #define MACH_SGI_IP32 3 /* O2 */ #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 */ diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 6cd147764f1..715d7c8ade5 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); -- GitLab From 4c642f3f5e9f3f1a2fcce2c3fa1a94bf80142202 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 13 Jul 2008 23:37:56 +0900 Subject: [PATCH 2147/2509] [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 --- arch/mips/Makefile | 2 +- arch/mips/txx9/generic/setup.c | 10 ++++++++++ arch/mips/txx9/jmr3927/setup.c | 4 ++-- .../{mach-jmr3927 => mach-tx39xx}/ioremap.h | 8 ++++---- .../{mach-jmr3927 => mach-tx39xx}/mangle-port.h | 13 +++++++++---- .../asm-mips/{mach-jmr3927 => mach-tx39xx}/war.h | 6 +++--- 6 files changed, 29 insertions(+), 14 deletions(-) rename include/asm-mips/{mach-jmr3927 => mach-tx39xx}/ioremap.h (85%) rename include/asm-mips/{mach-jmr3927 => mach-tx39xx}/mangle-port.h (55%) rename include/asm-mips/{mach-jmr3927 => mach-tx39xx}/war.h (85%) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index c4a3098a58c..356453322b4 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 517828e1ec9..452cb9ea12c 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 43a8dad22ef..61edc4ac1db 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-tx39xx/ioremap.h similarity index 85% rename from include/asm-mips/mach-jmr3927/ioremap.h rename to include/asm-mips/mach-tx39xx/ioremap.h index 29989ff10d6..93c6c04ffda 100644 --- a/include/asm-mips/mach-jmr3927/ioremap.h +++ b/include/asm-mips/mach-tx39xx/ioremap.h @@ -1,13 +1,13 @@ /* - * include/asm-mips/mach-jmr3927/ioremap.h + * 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_JMR3927_IOREMAP_H -#define __ASM_MACH_JMR3927_IOREMAP_H +#ifndef __ASM_MACH_TX39XX_IOREMAP_H +#define __ASM_MACH_TX39XX_IOREMAP_H #include @@ -35,4 +35,4 @@ static inline int plat_iounmap(const volatile void __iomem *addr) return (unsigned long)addr >= TXX9_DIRECTMAP_BASE; } -#endif /* __ASM_MACH_JMR3927_IOREMAP_H */ +#endif /* __ASM_MACH_TX39XX_IOREMAP_H */ diff --git a/include/asm-mips/mach-jmr3927/mangle-port.h b/include/asm-mips/mach-tx39xx/mangle-port.h similarity index 55% rename from include/asm-mips/mach-jmr3927/mangle-port.h rename to include/asm-mips/mach-tx39xx/mangle-port.h index 11bffcd1043..ef0b502fd8b 100644 --- a/include/asm-mips/mach-jmr3927/mangle-port.h +++ b/include/asm-mips/mach-tx39xx/mangle-port.h @@ -1,7 +1,12 @@ -#ifndef __ASM_MACH_JMR3927_MANGLE_PORT_H -#define __ASM_MACH_JMR3927_MANGLE_PORT_H +#ifndef __ASM_MACH_TX39XX_MANGLE_PORT_H +#define __ASM_MACH_TX39XX_MANGLE_PORT_H -extern unsigned long __swizzle_addr_b(unsigned long port); +#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) @@ -15,4 +20,4 @@ extern unsigned long __swizzle_addr_b(unsigned long port); #define ioswabq(a, x) le64_to_cpu(x) #define __mem_ioswabq(a, x) (x) -#endif /* __ASM_MACH_JMR3927_MANGLE_PORT_H */ +#endif /* __ASM_MACH_TX39XX_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-jmr3927/war.h b/include/asm-mips/mach-tx39xx/war.h similarity index 85% rename from include/asm-mips/mach-jmr3927/war.h rename to include/asm-mips/mach-tx39xx/war.h index 1ff55fb3fbc..43381461635 100644 --- a/include/asm-mips/mach-jmr3927/war.h +++ b/include/asm-mips/mach-tx39xx/war.h @@ -5,8 +5,8 @@ * * Copyright (C) 2002, 2004, 2007 by Ralf Baechle */ -#ifndef __ASM_MIPS_MACH_JMR3927_WAR_H -#define __ASM_MIPS_MACH_JMR3927_WAR_H +#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 @@ -22,4 +22,4 @@ #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 -#endif /* __ASM_MIPS_MACH_JMR3927_WAR_H */ +#endif /* __ASM_MIPS_MACH_TX39XX_WAR_H */ -- GitLab From 7b22609442a32050e37cec5f6735376af61e68a1 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 14 Jul 2008 00:15:04 +0900 Subject: [PATCH 2148/2509] [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 --- arch/mips/txx9/generic/setup.c | 2 +- arch/mips/txx9/jmr3927/setup.c | 3 --- arch/mips/txx9/rbtx4927/setup.c | 16 +++------------- arch/mips/txx9/rbtx4938/setup.c | 13 +++---------- include/asm-mips/txx9/generic.h | 1 + 5 files changed, 8 insertions(+), 27 deletions(-) diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 452cb9ea12c..5afc5d5cab0 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 61edc4ac1db..5e35ef73c5a 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 aba11f376a5..1657fd935da 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 2ef71adea82..aaa987ae0f8 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 715d7c8ade5..d8756660523 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 */ -- GitLab From 9528356308ecd2fb6368472615996a8602c02964 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:34:48 +0900 Subject: [PATCH 2149/2509] [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 --- arch/mips/au1000/mtx-1/platform.c | 51 ++++++++++++++++- drivers/mtd/maps/Kconfig | 7 --- drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/mtx-1_flash.c | 95 ------------------------------- 4 files changed, 50 insertions(+), 104 deletions(-) delete mode 100644 drivers/mtd/maps/mtx-1_flash.c diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c index 9807be37c32..8b5914d1241 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 17bc87a43ff..d2fbc296452 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 957fb5f70f5..c6ce8673dab 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 2a8fde9b92f..00000000000 --- 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"); -- GitLab From c660729501894e0b88054ad4b66a5f98a1a2a37e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 15:11:40 +0200 Subject: [PATCH 2150/2509] [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 --- arch/mips/fw/arc/identify.c | 11 ----------- arch/mips/jazz/setup.c | 3 +-- include/asm-mips/bootinfo.h | 21 --------------------- 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/arch/mips/fw/arc/identify.c b/arch/mips/fw/arc/identify.c index 23066985a73..0ce9acf10c3 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 f136c8a8591..f60524e8bc4 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 c70848d4f63..653096a69d1 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -25,13 +25,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 */ @@ -47,20 +40,6 @@ #define MACH_DS5800 9 /* DECsystem 5800 */ #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 */ -- GitLab From 0b56fd8c7abbf85baeecb77be25c54d3c7d11587 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 15:54:30 +0200 Subject: [PATCH 2151/2509] [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 --- arch/mips/emma2rh/common/prom.c | 15 +++++++-------- include/asm-mips/bootinfo.h | 5 ----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/mips/emma2rh/common/prom.c b/arch/mips/emma2rh/common/prom.c index 0f791eb6bb6..5e92b3a9c5b 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 653096a69d1..51dbec9dabf 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -46,11 +46,6 @@ #define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ #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 */ -- GitLab From b27418aa551a153e8bf1bd16cf93e5786f9590a9 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 16:58:47 +0200 Subject: [PATCH 2152/2509] [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 --- arch/mips/lasat/interrupt.c | 21 ++++++++------------- arch/mips/lasat/lasat_board.c | 3 +-- arch/mips/lasat/prom.c | 8 +++----- arch/mips/lasat/serial.c | 3 +-- arch/mips/lasat/setup.c | 8 +++++--- arch/mips/pci/pci-lasat.c | 14 ++++---------- include/asm-mips/bootinfo.h | 6 ------ include/asm-mips/lasat/lasat.h | 2 ++ 8 files changed, 24 insertions(+), 41 deletions(-) diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index a56c1502696..d1ac7a25c85 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 31e328b3814..577bb463a87 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 209edcc26f0..6acc6cb85f0 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 205bd397d75..5bcb6e89ab7 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 e072da4ff3b..dbd3163a85c 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 e70ae3236e0..a98e543a514 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 51dbec9dabf..d39e143b4a3 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -40,12 +40,6 @@ #define MACH_DS5800 9 /* DECsystem 5800 */ #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 */ diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h index ea04d9262ed..caeba1e302a 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 -- GitLab From 14351760e314b8a9720804b11c6bd11d0c0b1258 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Jul 2008 11:01:39 -0700 Subject: [PATCH 2153/2509] 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 --- drivers/clocksource/acpi_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index bcd7d0e429e..5ca1d80de18 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; -- GitLab From 8c6e46ddb343004e33653f62f0b09c0721cd8c12 Mon Sep 17 00:00:00 2001 From: Mikhail Cherkashin Date: Tue, 15 Jul 2008 21:21:40 +0200 Subject: [PATCH 2154/2509] 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 --- drivers/ide/arm/palm_bk3710.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 2f2b4f4cf22..74a05dc6d1e 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, -- GitLab From 5ddee516dae1acc779b36cb7565720a80503196d Mon Sep 17 00:00:00 2001 From: Mikhail Cherkashin Date: Tue, 15 Jul 2008 21:21:40 +0200 Subject: [PATCH 2155/2509] 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 --- drivers/ide/ide-iops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0daf923541f..c2dd20aa15a 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; -- GitLab From d6cddd3cac6650f273a2595c9f403aacee01ab05 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: [PATCH 2156/2509] 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 --- drivers/ide/ide-timing.h | 1 - drivers/ide/pci/amd74xx.c | 14 +++++++------- drivers/ide/pci/via82cxxx.c | 14 +++++++------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 3b12ffe7707..2e91c5870b4 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 efcf54338be..a373101747b 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 566e0ecb8db..e8c2570003f 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; } -- GitLab From a792bd5a407872714942f50bf24083874ce03745 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: [PATCH 2157/2509] 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 --- drivers/ide/ide-tape.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1e1f26331a2..2d822df0865 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], -- GitLab From 5d0cc8ae29b310ceb6516a6840ca22738aab7820 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: [PATCH 2158/2509] ide: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Cc: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2d822df0865..1a96cc50399 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); } -- GitLab From e8a96aa71355edef9f40ce01459acf25c50cb78c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: [PATCH 2159/2509] 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 --- drivers/ide/ide-cd.c | 1 + drivers/ide/ide-floppy.c | 1 + drivers/ide/ide-io.c | 7 +++---- drivers/ide/ide-tape.c | 1 + drivers/ide/ide.c | 1 + drivers/scsi/ide-scsi.c | 1 + 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 68e7f19dc03..ff8815937d3 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 f05fbc2bd7a..7d75240c2e2 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 696525342e9..5aed79ed458 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 1a96cc50399..d67a1789178 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 300431d080a..c9a05721360 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 44d8d5163a1..89ecf013219 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; -- GitLab From c6866a6ff571eebebda45bf14b5b62188768893a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: [PATCH 2160/2509] 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 --- drivers/ide/ide-io.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 5aed79ed458..1eb3f5cce55 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; -- GitLab From 5f828546e1acb45678e73d3a9a796c1a3a8c7846 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: [PATCH 2161/2509] 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 --- drivers/ide/ide-cd.c | 96 +++++++++++++++++++---------------- drivers/ide/ide-cd.h | 3 +- drivers/ide/ide-cd_ioctl.c | 101 ++++++++++++++++++------------------- 3 files changed, 103 insertions(+), 97 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ff8815937d3..792a3cf73d6 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 a58801c4484..df01cfd797c 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 6d147ce6782..85127707430 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; } -- GitLab From 0ef4c4db7faabe4fb8a516e9e991e1e8e87a647f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: [PATCH 2162/2509] 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 --- drivers/ide/ide-cd_ioctl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 85127707430..24d002addf7 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. -- GitLab From dd47087bc173a84e8c42644b315d38b30dc02263 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: [PATCH 2163/2509] 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 --- drivers/ide/ide-disk.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8e08d083fce..c5f22ef8ed2 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; } -- GitLab From 6fe162381e547f457252e68521eb42fd36ec1418 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: [PATCH 2164/2509] 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 --- drivers/ide/ide-floppy.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 7d75240c2e2..b10e9a813cd 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; } /* -- GitLab From 154ed280e3f48995d0689b57f10b7063add63019 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: [PATCH 2165/2509] 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 --- drivers/ide/ide-taskfile.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index ab545ffa154..b6a1c4b5112 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)) -- GitLab From 64ea1b4ab7f51c5de601d291a51508c27d445f70 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: [PATCH 2166/2509] 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 --- drivers/ide/ide-tape.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d67a1789178..a5f0b774527 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) -- GitLab From 9a2d43b7566caeeeb414aa628bc2759028897dbb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: [PATCH 2167/2509] 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 --- block/blk-exec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/blk-exec.c b/block/blk-exec.c index 391dd622489..4f52f279205 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); -- GitLab From 5b114715ed63f3a4fdf790f5df61364fc4adadf1 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: [PATCH 2168/2509] 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 --- drivers/ide/ide.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c9a05721360..8823df1b871 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); -- GitLab From 5f2e1ceef45ac07d7c52d16de2531a56c453bb0f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: [PATCH 2169/2509] 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 --- drivers/ide/ide-io.c | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1eb3f5cce55..29f5cc863f6 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); -- GitLab From 124cafc5eb973e748c4ce3dc1caad29274e64613 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: [PATCH 2170/2509] 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 --- drivers/ide/ide-cd.c | 2 +- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-io.c | 17 ----------------- drivers/scsi/ide-scsi.c | 4 ++-- include/linux/ide.h | 2 -- 5 files changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 792a3cf73d6..7917cd57644 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 b10e9a813cd..9161cd92a84 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 29f5cc863f6..d8b4d9f81ae 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1538,23 +1538,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) return IRQ_HANDLED; } -/** - * 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 diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 89ecf013219..da261806d62 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 eddb6daadf4..3261c669175 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. */ -- GitLab From ed820f19521de246c5b7978f8f78290733a55b20 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: [PATCH 2171/2509] 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 --- drivers/ide/ide-cd.c | 14 +++----------- drivers/ide/ide-cd.h | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 7917cd57644..ac542ffffa4 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 df01cfd797c..fe0ea36e412 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 *); -- GitLab From d79c5a670ddf076a346ddcf3d9e21785ecab963f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: [PATCH 2172/2509] 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 --- drivers/block/paride/pd.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 570f3b70dce..5fdfa7c888c 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; } -- GitLab From 52a93ba815737e3877f85b46850cffe993a22429 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: [PATCH 2173/2509] 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 --- block/blk-core.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 1905aaba49f..ac83cf9a19a 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); -- GitLab From 681a561b7ec7fdcd8f35b68e44ac6d6c70aecc04 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: [PATCH 2174/2509] 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 --- block/blk-exec.c | 3 +-- include/linux/blkdev.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/block/blk-exec.c b/block/blk-exec.c index 4f52f279205..9bceff7674f 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 d2a1b71e93c..1171abd7eb1 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 *); -- GitLab From 30e5ee4d1a651a0c66e86c6612c003034bd20ba2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: [PATCH 2175/2509] 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 --- drivers/ide/ide.c | 71 +----------------------------------- drivers/ide/legacy/ali14xx.c | 2 +- drivers/ide/legacy/ht6560b.c | 2 +- drivers/ide/legacy/qd65xx.c | 4 +- drivers/ide/pci/aec62xx.c | 2 +- drivers/ide/pci/alim15x3.c | 2 +- drivers/ide/pci/amd74xx.c | 2 +- drivers/ide/pci/cmd640.c | 8 ++-- drivers/ide/pci/cmd64x.c | 4 +- drivers/ide/pci/cy82c693.c | 2 +- drivers/ide/pci/via82cxxx.c | 2 +- include/linux/ide.h | 2 - 12 files changed, 15 insertions(+), 88 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 8823df1b871..f65be738b16 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 90c65cf9744..052125fafcf 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 4fe516df9f7..dd6dfb32e85 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 6424af15432..51dba82f881 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 7f46c224b7c..ae7a4329a58 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 f2129d5e07f..f2de00adf14 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 a373101747b..ad222206a42 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 b38a1980dcd..cd1ba14984a 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 08674711d08..ca4774aa27e 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 77cc22c2ad4..8c534afcb6c 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 e8c2570003f..3ed9728abd2 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 3261c669175..dad53565924 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 *); -- GitLab From 232595eaff951e96cabe5e85fed35f66b72ff51e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: [PATCH 2176/2509] ide: remove obsoleted "hdx=" kernel parameters * Remove obsoleted "hdx=" kernel parameters. * Remove no longer used stridx() and match_parm(). Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/kernel-parameters.txt | 3 - drivers/ide/ide.c | 139 +--------------------------- 2 files changed, 1 insertion(+), 141 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b52f47d588b..faeea507cdc 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 f65be738b16..6f600d81a97 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -721,90 +721,14 @@ 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: -- GitLab From dbac9f895f628deebc99dee86dfd21c1823013c3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: [PATCH 2177/2509] 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 --- drivers/ide/ide.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6f600d81a97..e8c88ff2f6b 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")) { -- GitLab From 931ee0dc5c69e8113233d21942681ab8fecde7f9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: [PATCH 2178/2509] 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 --- drivers/ide/ide-acpi.c | 6 +-- drivers/ide/ide-dma.c | 2 +- drivers/ide/ide.c | 91 +++----------------------------------- drivers/ide/legacy/gayle.c | 4 +- include/linux/ide.h | 4 -- 5 files changed, 10 insertions(+), 97 deletions(-) diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 9d3601fa568..6f704628c27 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 653b1ade13d..174f4704614 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 e8c88ff2f6b..1defba3eefe 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 fed7d812761..b78941680c3 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 dad53565924..0fa1812d043 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; -- GitLab From 57279a7a401eed844ded4346c5ff512e622ac1de Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: [PATCH 2179/2509] 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 --- drivers/ide/ide-io.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index d8b4d9f81ae..c22a337ced4 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); -- GitLab From 912ef6d94cc07ce5db19a8ed8953676727d4f30c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: [PATCH 2180/2509] 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 --- drivers/ide/pci/sgiioc4.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 16a0bce17d6..c1b667c53f2 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); -- GitLab From 49e153e68187454e296f1e03442393f1a3f1d69c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: [PATCH 2181/2509] ide: remove commented out code from ide_config_drive_speed() Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c2dd20aa15a..2de4c8f581e 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); -- GitLab From e81a3bde13343bc36613aff8f864def7171b376a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: [PATCH 2182/2509] 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 --- drivers/ide/ide-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 26e68b65b7c..12513c45d70 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); -- GitLab From 9a410e79b552bacb4481f85618aa7333b7776ed7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: [PATCH 2183/2509] 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 --- drivers/ide/ide-cd.c | 4 ++-- drivers/ide/ide-disk.c | 3 +-- drivers/ide/ide-floppy.c | 3 +-- drivers/ide/ide-iops.c | 4 +--- drivers/ide/ide-tape.c | 3 +-- drivers/scsi/ide-scsi.c | 2 +- include/linux/ide.h | 1 - 7 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ac542ffffa4..0fbc2d8d0d5 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 c5f22ef8ed2..5f49a4ae9dd 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 9161cd92a84..1852008d9ee 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 2de4c8f581e..9f9916fe6c2 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 a5f0b774527..cc7991c7c25 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 da261806d62..3222aa589db 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 0fa1812d043..d4a910cdb90 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), -- GitLab From ed4af48fd660176680da905817f6e40d51436e4c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: [PATCH 2184/2509] 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 --- drivers/ide/h8300/ide-h8300.c | 2 -- drivers/ide/ide-io.c | 2 ++ drivers/ide/ide-iops.c | 5 +---- drivers/ide/ide-taskfile.c | 2 ++ drivers/ide/pci/scc_pata.c | 2 -- include/linux/ide.h | 1 + 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index ecf53bb0d2a..d5afc28eaae 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 c22a337ced4..2083cc08b2c 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 9f9916fe6c2..491980aab86 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 b6a1c4b5112..6a17ab54f80 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 910fb00deb7..37e8cfcabb4 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 d4a910cdb90..56d0bc2dffe 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 *); -- GitLab From 135721446144af005109c25eeacca4fdddcd9a66 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:49 +0200 Subject: [PATCH 2185/2509] 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 --- drivers/ide/arm/palm_bk3710.c | 1 - drivers/ide/ide-dma.c | 2 +- drivers/ide/pci/scc_pata.c | 1 - drivers/ide/pci/siimage.c | 25 +++++++++++++------------ drivers/ide/setup-pci.c | 4 ++-- include/linux/ide.h | 1 - 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 74a05dc6d1e..3839f572298 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 174f4704614..7ee44f86bc5 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 37e8cfcabb4..133053c7a48 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 0006b9e5856..b75e9bb390a 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 5171601fb25..abcfb1739d4 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 56d0bc2dffe..b01b102be4d 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; -- GitLab From f8c4bd0ab2b8783c0f080957781e9f70bee48eaa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:49 +0200 Subject: [PATCH 2186/2509] ide: pass 'hwif *' instead of 'drive *' to ->OUTBSYNC method There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 2 +- drivers/ide/ide-iops.c | 18 +++++++++--------- drivers/ide/ide-probe.c | 6 +++--- drivers/ide/ide-taskfile.c | 2 +- drivers/ide/pci/scc_pata.c | 5 +---- drivers/ide/ppc/pmac.c | 6 +++--- drivers/scsi/ide-scsi.c | 2 +- include/linux/ide.h | 2 +- 8 files changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2083cc08b2c..c28fcdf0ee9 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 491980aab86..4c32cf0b623 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 12513c45d70..b010633eb5b 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 6a17ab54f80..cf55a48a7dd 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 133053c7a48..32eb0877fce 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 ba2d5872796..dcb2c466bb9 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 3222aa589db..d7fd5e550a2 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 b01b102be4d..1c343146964 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); -- GitLab From 6a732e11be1355baeeca7c47f19ab20e7baa6ce7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: [PATCH 2187/2509] ide: use ->OUTBSYNC in init_irq() Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index b010633eb5b..809362b13c9 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; -- GitLab From 0fd04dcc2ebb6ec9088c24b368b0ce1f42a98ef5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: [PATCH 2188/2509] ide: use ->OUTBSYNC in ide_set_irq() Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index 1c343146964..4d1c9714f1d 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) -- GitLab From ff07488346702f554aaeb6aae982540aa0302373 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: [PATCH 2189/2509] 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 --- drivers/ide/h8300/ide-h8300.c | 4 ++-- drivers/ide/ide-iops.c | 10 +++++----- drivers/ide/ide-probe.c | 2 +- drivers/ide/ide.c | 1 - drivers/ide/pci/hpt366.c | 3 +-- drivers/ide/pci/ns87415.c | 4 ++-- drivers/ide/pci/scc_pata.c | 4 ++-- drivers/ide/pci/sgiioc4.c | 2 +- include/linux/ide.h | 3 +-- 9 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index d5afc28eaae..ae37ee58bae 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 4c32cf0b623..80ad4f234f3 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 809362b13c9..d21e51a02c3 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 1defba3eefe..2b8453510e0 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 c929dadaaaf..397c6cbe953 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 a7a41bb8277..45ba71a7182 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 32eb0877fce..1584ebb6a18 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 c1b667c53f2..24513e3dcd6 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 4d1c9714f1d..d8c86f0362c 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); } -- GitLab From 7e12ca11d65f4cb29ed58ea3948f8c5d4f57b35e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: [PATCH 2190/2509] 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 --- drivers/scsi/ide-scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d7fd5e550a2..58e30efe7a7 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: -- GitLab From 63f5abb0959337db0d5bece9cefba03cdcadec51 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: [PATCH 2191/2509] 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 --- drivers/ide/ide-cd.c | 2 +- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-io.c | 40 +++++++++------------------------------- drivers/ide/ide-tape.c | 2 +- drivers/scsi/ide-scsi.c | 3 ++- include/linux/ide.h | 12 +----------- 6 files changed, 15 insertions(+), 46 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 0fbc2d8d0d5..043129c422f 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 1852008d9ee..53209a47393 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 c28fcdf0ee9..28057747c1f 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 cc7991c7c25..a562df82077 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 58e30efe7a7..569ffde6d04 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 d8c86f0362c..04267dc1edf 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); -- GitLab From b3d96afccf8b5c67b66a61efb88c53ff029c6611 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: [PATCH 2192/2509] 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 --- drivers/scsi/ide-scsi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 569ffde6d04..2553ef4d5a9 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; } -- GitLab From e8e25f03e19c2c47834c821511625c0b80567827 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: [PATCH 2193/2509] 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 --- drivers/scsi/ide-scsi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2553ef4d5a9..e67cf8aa946 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); -- GitLab From c04bbc812b05b304a9118687d0e0a47e35f00d1d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: [PATCH 2194/2509] 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 --- drivers/scsi/ide-scsi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index e67cf8aa946..ed92cf7a768 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; -- GitLab From 6c60bd8ea7aa536d67830bc8384ef0ebdfb8aad4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: [PATCH 2195/2509] 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 --- drivers/scsi/ide-scsi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ed92cf7a768..08807070e08 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; -- GitLab From 3e52fb4d1f4cc9630422982b6c5fa571e30f9889 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: [PATCH 2196/2509] 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 --- drivers/scsi/ide-scsi.c | 81 ++++++++++++----------------------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 08807070e08..36c2c3bf111 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; -- GitLab From c8c51129805c0efb32f34afd3af8fe94f5757363 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: [PATCH 2197/2509] 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 --- drivers/scsi/ide-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 36c2c3bf111..e9d3dbf596c 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); -- GitLab From 43a2b5b29385a3e0997a47c86f286d3645e5cb44 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: [PATCH 2198/2509] 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 --- drivers/scsi/ide-scsi.c | 51 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index e9d3dbf596c..d2dad9039e0 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 -- GitLab From 87429bdc2e0701fa33a455297de01e79797b4210 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: [PATCH 2199/2509] ide-tape: idetape_pc_intr() should use local_irq_enable_in_hardirq() Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a562df82077..58c5a5a9885 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) && -- GitLab From 1e049a8ea190b7cc22320c7797b36b2c6128c9c5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: [PATCH 2200/2509] 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 --- drivers/ide/ide-tape.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 58c5a5a9885..92fadd5a5f8 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); } -- GitLab From 6bd3b0bfb8fccdcce3b8524d6761e0a3ab6e23f0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: [PATCH 2201/2509] 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 --- drivers/ide/ide-tape.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 92fadd5a5f8..5aa7e2dbaa0 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) -- GitLab From 91395a16309596c2e78439aa5f9f6004f0365ef9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: [PATCH 2202/2509] 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 --- drivers/ide/ide-tape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 5aa7e2dbaa0..b8cc0d5cde0 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); -- GitLab From 531e9e50543ebf562237b8ac64529ae09b344a43 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: [PATCH 2203/2509] ide-tape: remove stale comments from idetape_pc_intr() Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b8cc0d5cde0..41aa8b3ccab 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; -- GitLab From 170ee569bbe1005baebf2e9e4c3f4622d14ec851 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: [PATCH 2204/2509] ide-tape: remove SIMULATE_ERRORS debug code Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 41aa8b3ccab..cc70e759fc8 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)) { -- GitLab From 0b2eea4c5594ceaf13c57eaff7ff226263f1c36f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: [PATCH 2205/2509] 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 --- drivers/ide/ide-floppy.c | 65 +++++++++++----------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 53209a47393..8dbb340dbfc 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -521,40 +521,6 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) return ide_started; } -/* - * 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 @@ -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); } } -- GitLab From 568ca92774d2f6be4a7e2f8357559bfdc9424056 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: [PATCH 2206/2509] 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 --- drivers/ide/ide-floppy.c | 35 +++++++++++++++++---------------- drivers/ide/ide-tape.c | 42 +++++++++++++++++++++------------------- drivers/scsi/ide-scsi.c | 24 ++++++++++++----------- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 8dbb340dbfc..dae1c90d421 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 cc70e759fc8..8f10211c2b0 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 d2dad9039e0..5b8a1931ac9 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); } -- GitLab From 258ec4113081c2b63117dc2df6d94c3e484e9747 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: [PATCH 2207/2509] 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 --- drivers/ide/ide-tape.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8f10211c2b0..48fccf154f6 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) -- GitLab From 5985e6abbd89f969c17fd80ab864c80f089827a3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: [PATCH 2208/2509] 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 --- drivers/ide/ide-tape.c | 168 ++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 104 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 48fccf154f6..d387aaf0eb3 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. */ -- GitLab From 92f5daff2b8439fa4c57c57f47823ffc459c3bd9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: [PATCH 2209/2509] 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 --- drivers/ide/ide-tape.c | 13 +++++++------ include/linux/ide.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d387aaf0eb3..88d26efdf84 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 04267dc1edf..8936b21a703 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; -- GitLab From 81f4938239fea86d0a7529194a37fb81041171e0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: [PATCH 2210/2509] 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 --- drivers/ide/ide-floppy.c | 69 ++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index dae1c90d421..2058a6f3f33 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; -- GitLab From 1b06e92aa03018e4b3ba281e03a7711d9b71a998 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: [PATCH 2211/2509] 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 --- drivers/ide/ide-floppy.c | 6 +++--- drivers/ide/ide-tape.c | 8 ++++---- include/linux/ide.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 2058a6f3f33..a9f3127a74e 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 88d26efdf84..ce9b6d32752 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 8936b21a703..f079456adfd 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; -- GitLab From 5e3310958204912f3f00be2592c945fbc37db6ae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: [PATCH 2212/2509] 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 --- drivers/ide/ide-floppy.c | 6 +++--- drivers/ide/ide-tape.c | 6 +++--- include/linux/ide.h | 9 ++++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index a9f3127a74e..dbefe35c139 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 ce9b6d32752..e8a5852fa2d 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 f079456adfd..63cee2947f6 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 { -- GitLab From 6ffb66410dd9f5f383d9265d51ab667333a8296c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: [PATCH 2213/2509] 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 --- drivers/ide/ide-floppy.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index dbefe35c139..1df6a314359 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 */ -- GitLab From 9fd13a27c8a35ff1986793cb96aaedb5e75b5368 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: [PATCH 2214/2509] 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 --- drivers/ide/ide-tape.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index e8a5852fa2d..1ce8b31453c 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); -- GitLab From 5a7b75ab429e9ed568be50cfbf7091f097457cb8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: [PATCH 2215/2509] 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 --- drivers/ide/ide-tape.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1ce8b31453c..63b837ef7e0 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); -- GitLab From 5d41893c0f9caf94b449eada0279a08c86f0212e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: [PATCH 2216/2509] 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 --- drivers/ide/ide-floppy.c | 8 ++++++-- include/linux/ide.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 1df6a314359..cff90c4b217 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 63cee2947f6..89feaea9e20 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 { -- GitLab From 794cc6804bb946826b7427d205ac391a5370d361 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: [PATCH 2217/2509] 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 --- drivers/ide/ide-cd.c | 5 ----- drivers/ide/ide-floppy.c | 5 ----- drivers/ide/ide-tape.c | 5 ----- 3 files changed, 15 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 043129c422f..d9984715718 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 cff90c4b217..a7c138dc324 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 63b837ef7e0..2a362138f97 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", -- GitLab From f83cbc77b0d5521b4f0f591ede4870316944481a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: [PATCH 2218/2509] 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 --- drivers/scsi/ide-scsi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 5b8a1931ac9..c9fdf60c9dc 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; } -- GitLab From 594c16d8dd54cd7b1c5ef1ec3ac0f6bf34301dad Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: [PATCH 2219/2509] 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 --- drivers/ide/Kconfig | 6 ++++ drivers/ide/Makefile | 1 + drivers/ide/ide-atapi.c | 70 ++++++++++++++++++++++++++++++++++++++++ drivers/ide/ide-floppy.c | 28 +--------------- drivers/ide/ide-tape.c | 56 ++------------------------------ drivers/scsi/ide-scsi.c | 30 ++--------------- include/linux/ide.h | 3 ++ 7 files changed, 85 insertions(+), 109 deletions(-) create mode 100644 drivers/ide/ide-atapi.c diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1607536ff5f..cf707c8f08d 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 f94b679b611..a2b3f84d710 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 00000000000..25939bc6040 --- /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 a7c138dc324..e7a1025c03c 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 2a362138f97..5adc2c9ae41 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 c9fdf60c9dc..d41348f2245 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 89feaea9e20..bed3c58798a 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); -- GitLab From 4cc196897de9e6c02cf86debc5b9f7cf1b69a214 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: [PATCH 2220/2509] 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 --- drivers/scsi/ide-scsi.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d41348f2245..1d261298d61 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); -- GitLab From 28c7214bd8c2bbd4873b8f1e7f58d86d3731124f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:59 +0200 Subject: [PATCH 2221/2509] 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 --- drivers/ide/ide-floppy.c | 5 ++++- drivers/ide/ide-tape.c | 11 ++++++++--- drivers/scsi/ide-scsi.c | 6 +++++- include/linux/ide.h | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e7a1025c03c..13f650fa212 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 5adc2c9ae41..cba18a67550 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 1d261298d61..b7c5e839157 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 bed3c58798a..c2274ad44b2 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 { -- GitLab From 6bf1641ca1c7554f0da54aaf89788731b541bacc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:00 +0200 Subject: [PATCH 2222/2509] 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 --- drivers/ide/ide-atapi.c | 49 ++++++++++++++++++++++++++++++++++++++++ drivers/ide/ide-floppy.c | 35 ++-------------------------- drivers/ide/ide-tape.c | 30 ++---------------------- drivers/scsi/ide-scsi.c | 30 ++---------------------- include/linux/ide.h | 2 ++ 5 files changed, 57 insertions(+), 89 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 25939bc6040..932a83abaf0 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 13f650fa212..e658aafc51d 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 cba18a67550..7907a1e4191 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 b7c5e839157..32415466fbf 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 c2274ad44b2..fee07a7edb1 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 *); -- GitLab From dd2e9a032bc552f6e2ae852e81cde602c09d7d3e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: [PATCH 2223/2509] 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 --- --- drivers/ide/ide-floppy.c | 5 +++-- drivers/ide/ide-tape.c | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e658aafc51d..b1d6905fd8e 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 7907a1e4191..0fec58ebee8 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; -- GitLab From 74e63e74ea57e06839aa5fcf016eace35da26050 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: [PATCH 2224/2509] 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 --- drivers/ide/ide-tape.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0fec58ebee8..b224823a8ae 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 */ -- GitLab From 08424ac24a35b505463919a897b097f27e4dca96 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: [PATCH 2225/2509] 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 --- --- drivers/ide/ide-tape.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b224823a8ae..6801c68ee7d 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); -- GitLab From 3e421d324c003f8f002f402141b15d758adbfaef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: [PATCH 2226/2509] 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 --- drivers/ide/ide-tape.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 6801c68ee7d..10f2d333628 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 */ -- GitLab From 4c93067ea9e5eca9d975bec74dae641228ac1bbe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: [PATCH 2227/2509] 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 --- drivers/ide/ide-floppy.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index b1d6905fd8e..502ef9dcc5b 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; -- GitLab From c6b2d260b5a7a5ed32aa2ce370d81183fc37eeb1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: [PATCH 2228/2509] 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 --- drivers/scsi/ide-scsi.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 32415466fbf..c0b39b9e5c1 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); -- GitLab From cdca5c1f3b769eb2cdfc9cadc254cb74ba73c7d6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: [PATCH 2229/2509] 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 --- drivers/scsi/ide-scsi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c0b39b9e5c1..ec9a5de2e75 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; -- GitLab From 55d82bfa6763d6761670d740ab3bac2f1c042d87 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: [PATCH 2230/2509] 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 --- drivers/ide/ide-floppy.c | 6 +++--- drivers/scsi/ide-scsi.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 502ef9dcc5b..70aef97fb8b 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 ec9a5de2e75..ada733ca672 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", -- GitLab From 646c0cb6c430f8d3ad3769dd1518fe664ff0ce27 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: [PATCH 2231/2509] 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 --- drivers/ide/ide-atapi.c | 177 +++++++++++++++++++++++++++++++++++++++ drivers/ide/ide-floppy.c | 128 +--------------------------- drivers/ide/ide-tape.c | 132 ++--------------------------- drivers/scsi/ide-scsi.c | 115 +------------------------ include/linux/ide.h | 6 ++ 5 files changed, 195 insertions(+), 363 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 932a83abaf0..2802031de67 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 70aef97fb8b..0f3602a5efb 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 10f2d333628..0afa109ec99 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 ada733ca672..683bce375c7 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 fee07a7edb1..ac4eeb2932e 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 *, -- GitLab From cd2abbfec84f43db740483daf4ea528d49d8858f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: [PATCH 2232/2509] 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 --- drivers/ide/ide-tape.c | 45 +++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0afa109ec99..6e1233bdf3a 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) { -- GitLab From cbbc4e818de4451cdef75a112b7fc8a523d5d2a0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: [PATCH 2233/2509] 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 --- drivers/ide/ide-floppy.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0f3602a5efb..b3689437269 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); } -- GitLab From d93c768e66d8c3970187c179a91a2553b077d9e8 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 15 Jul 2008 20:11:21 +0200 Subject: [PATCH 2234/2509] pcmcia: fix return value in cm4000_cs.c should be -EINVAL, not EINVAL. Found by Peter Stuge. Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 59ca35156d8..e4a4fbd37d7 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"); -- GitLab From 002b90a1bf5fe9c8de7a8634403a685621841ff3 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 15 Jul 2008 15:26:15 +0200 Subject: [PATCH 2235/2509] 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 --- drivers/pcmcia/cistpl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 9fcff0c3361..65129b54eb0 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; -- GitLab From 417e1494fd70715b737428cc3c3d924255f22ba1 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 15 Jul 2008 11:30:00 -0500 Subject: [PATCH 2236/2509] 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 --- drivers/ide/legacy/ide-cs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 8dbf4d9b644..41a2e251d53 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 -- GitLab From b3c9816b9fa9a7b75ab36111eb76eca03e5bab78 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Jul 2008 22:03:56 +0200 Subject: [PATCH 2237/2509] 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 --- arch/x86/pci/amd_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index a18141ae3f0..dbf53236971 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; } -- GitLab From f6f88e9bfb6ced9871ed65ebe85c371de3c9e4be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Jul 2008 22:08:52 +0200 Subject: [PATCH 2238/2509] generic-ipi: more merge fallout fix more API change fallout in recently merged upstream changes. Signed-off-by: Ingo Molnar --- arch/mips/oprofile/op_model_mipsxx.c | 4 ++-- arch/ppc/kernel/smp.c | 2 +- arch/s390/kernel/time.c | 4 ++-- drivers/watchdog/booke_wdt.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index b40df7d2cf4..54759f1669d 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 055998575cb..bcab0d210e3 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 8051e9326df..f2cede3947b 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 c1ba0db4850..770824458d4 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); -- GitLab From 431ceb83f703a343bdd14350480a2224fa4bfedf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 22:08:04 +0200 Subject: [PATCH 2239/2509] 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 --- arch/x86/kernel/tsc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 3c36f92160c..7603c055390 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", -- GitLab From de3b69d7d87e1e86c0307f0f15b377dcebeab906 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 15 Jul 2008 13:28:14 -0400 Subject: [PATCH 2240/2509] 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 --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6198fa3deb9..fc6c005c531 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 -- GitLab From fe1a6875fcaaac2041945008a9875d2c07be1d9b Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 15 Jul 2008 22:28:46 +0200 Subject: [PATCH 2241/2509] 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 --- include/asm-generic/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 4fce3db2cec..ef87f889ef6 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 -- GitLab From 63cf13b77ab785e87c867defa8545e6d4a989774 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 15 Jul 2008 13:22:49 -0700 Subject: [PATCH 2242/2509] 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 --- kernel/smp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/smp.c b/kernel/smp.c index ab10793b070..462c785ca1e 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); -- GitLab From 987ff954cda2a206f5e694f267b0ccad869c257c Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:15:41 -0400 Subject: [PATCH 2243/2509] Fix endianity in A100U2W SCSI driver Support big endian systems in a100u2w driver. Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds --- drivers/scsi/a100u2w.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index ced3eebe252..1dd0fcfe1d7 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; -- GitLab From 56d387ec210049be2fdb0fe26ba6d6de1b3c1b15 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:16:38 -0400 Subject: [PATCH 2244/2509] 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 --- drivers/scsi/a100u2w.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 1dd0fcfe1d7..1e8bdd45783 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 */ -- GitLab From a5db33411ae762e597bfcde6bb9d0c8c2ea9c0eb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:18:38 -0400 Subject: [PATCH 2245/2509] 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 --- drivers/scsi/a100u2w.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 1e8bdd45783..f5051f4301d 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) { -- GitLab From 3a628b0fd42f7eaf9d052447784d48ceae9ffb8e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:19:55 -0400 Subject: [PATCH 2246/2509] 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 --- drivers/scsi/a100u2w.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index f5051f4301d..84bb6162837 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; } -- GitLab From 166b88d755f925139af7f7b75aa0a1b896ca0670 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:26 -0400 Subject: [PATCH 2247/2509] 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 --- net/sunrpc/rpcb_clnt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 24e93e0a0a2..0021fad464e 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), }; -- GitLab From cc5598b78fd320dd6d1f90c14491e08029f3c4f6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:27 -0400 Subject: [PATCH 2248/2509] 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 --- net/sunrpc/rpcb_clnt.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 0021fad464e..35c1ded1fc4 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); -- GitLab From 423d8b064771f5cd8b706a4839b18db9bb6c3c59 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:28 -0400 Subject: [PATCH 2249/2509] 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 --- net/sunrpc/rpcb_clnt.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 35c1ded1fc4..691bd216f46 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", -- GitLab From babe80eb4994dfdc97d5be19a68b5af66d667585 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:29 -0400 Subject: [PATCH 2250/2509] 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 --- net/sunrpc/rpcb_clnt.c | 48 ++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 691bd216f46..8b75c306e66 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); } /** -- GitLab From c2e1b09ff237c0a3687b9a804cc8bf489743cffc Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:30 -0400 Subject: [PATCH 2251/2509] 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 --- include/linux/sunrpc/clnt.h | 3 + net/sunrpc/rpcb_clnt.c | 178 +++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 4 deletions(-) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 764fd4c286e..e5bfe01ee30 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 8b75c306e66..24db2b4d12d 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 -- GitLab From d67d1c7bf948341fd8678c8e337ec27f4b46b206 Mon Sep 17 00:00:00 2001 From: Felix Blyakher Date: Tue, 15 Jul 2008 12:40:22 -0500 Subject: [PATCH 2252/2509] 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 --- fs/lockd/clntproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 5df517b81f3..fd7d4669776 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; -- GitLab From 1b83d707032a1be40a60ed0a9bd841662cc04a5d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:04 -0400 Subject: [PATCH 2253/2509] NFS: Protect inode->i_nlink updates using inode->i_lock Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b1940660502..d6ec1c85995 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: /* -- GitLab From a3d01454bc58b5a211ef64a7670572a40b71e682 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 12:21:19 -0400 Subject: [PATCH 2254/2509] 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 --- fs/nfs/inode.c | 67 +++++++++++++++++++++++++++++++++++++++++++++----- fs/nfs/write.c | 15 +++++++---- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2c23d067e2a..3adabd15477 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -388,6 +388,62 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) return error; } +/** + * 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 @@ -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 feca8c64876..3229e217c77 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 */ -- GitLab From fa6dc9dc59c3a76fd209a97c8cf37395980fb903 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:14 -0400 Subject: [PATCH 2255/2509] NFS: Remove attribute update related BKL references Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 4 ---- fs/nfs/super.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3adabd15477..df23f987da6 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 47cf83e917b..1b94e3650f5 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; } -- GitLab From 4d80f2ecd506d9732ad94a6da104580bb47680d6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:18 -0400 Subject: [PATCH 2256/2509] NFS: Remove the BKL from the permission checking code Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d6ec1c85995..73e0f9740dd 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; } -- GitLab From b6a2e569e2157509951c9f3f58dfa18b44ce91b3 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:16 -0400 Subject: [PATCH 2257/2509] NFS: Remove BKL usage from the write path Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 509dcb58959..f919d9a01a2 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); -- GitLab From bba67e0e3f4caba2b2b90b48ed798fb0461bcb86 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:23 -0400 Subject: [PATCH 2258/2509] 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 --- fs/nfs/dir.c | 6 ------ fs/nfs/file.c | 2 -- fs/nfs/nfs4proc.c | 2 -- 3 files changed, 10 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 73e0f9740dd..c68ec447ace 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 f919d9a01a2..9f1bed944b2 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 4451287a81d..c910413eaec 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; -- GitLab From f1e2eda23513b68003202bddf1f84158baad8844 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:50:50 -0400 Subject: [PATCH 2259/2509] 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 --- fs/nfs/dir.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c68ec447ace..d40e91e5c94 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; } -- GitLab From fc81af535e462764e17f638d542973fbef13b026 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:52:40 -0400 Subject: [PATCH 2260/2509] NFS: Remove the BKL from nfs_link() Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d40e91e5c94..5ae8ee6b298 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; } -- GitLab From fc0f684c21b5d4b41dc2ec76f7c0897ac98f5b6e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:20 -0400 Subject: [PATCH 2261/2509] 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 --- fs/nfs/dir.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5ae8ee6b298..60da7550133 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; } -- GitLab From bd9bb454b76fb6ca2d00f17313f9f9df5f5c404a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:09:59 -0400 Subject: [PATCH 2262/2509] 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 --- fs/nfs/dir.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 60da7550133..68e0688904e 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; } -- GitLab From 52e2e8d37e01edf38ccdccc983fb13ec1456d63d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:21 -0400 Subject: [PATCH 2263/2509] NFS: Remove BKL from the sillydelete operations Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 68e0688904e..1bdc36bf178 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; -- GitLab From 76566991f94c206d9c5881edcaf99ba72c9e9d61 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:22 -0400 Subject: [PATCH 2264/2509] 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 --- fs/nfs/dir.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1bdc36bf178..e5f95029192 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; } -- GitLab From c3cc8c019ca09767d7c9b5457d5cf8ac65085f44 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:23 -0400 Subject: [PATCH 2265/2509] 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 --- fs/nfs/dir.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e5f95029192..28a238dab23 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", -- GitLab From a86dc496b764ebb1431677b38eab45310e5a2ad4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:37:09 -0400 Subject: [PATCH 2266/2509] 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 --- fs/lockd/clntproc.c | 6 ++++++ fs/lockd/svc4proc.c | 2 ++ fs/lockd/svclock.c | 7 ++++++- fs/lockd/svcproc.c | 2 ++ net/sunrpc/sched.c | 9 +-------- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index fd7d4669776..1f6dc518505 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 385437e3387..2e27176ff42 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 81aca859bfd..56a08ab9a4c 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 88379cc6e0b..ce6952b50a7 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 6288af05c20..385f427beda 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(); - } } /* -- GitLab From f839c4c1991cc9b580ae38f98f54554938a7f49c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:26 -0400 Subject: [PATCH 2267/2509] NFSv4: Remove BKL from the nfsv4 state recovery Signed-off-by: Trond Myklebust --- fs/nfs/nfs4state.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 856a8934f61..401ef8b28f9 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); -- GitLab From 809d9a8f93bd8504dcc34b16bbfdfd1a8c9bb1ed Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 15 Jul 2008 11:59:42 -0700 Subject: [PATCH 2268/2509] 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 --- arch/x86/pci/acpi.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d95de2f199c..d1ffb570917 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; } -- GitLab From f2d9c740f6b9f92608dfb2a2bdd797e0350cabe4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 15 Jul 2008 10:57:33 -0400 Subject: [PATCH 2269/2509] 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 --- Documentation/ftrace.txt | 305 +++++++++++++++++++-------------------- 1 file changed, 152 insertions(+), 153 deletions(-) diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index 77d3faa1a61..f218f616ff6 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 -- GitLab From d25dc7fd4740decf4c66e2f17dbaa288448fabd5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 15 Jul 2008 22:54:04 -0700 Subject: [PATCH 2270/2509] 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 --- firmware/.gitignore | 6 ++++++ firmware/Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 firmware/.gitignore diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 00000000000..d9c69017bc9 --- /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 e4f2fb3d191..9fe86041f86 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 -- GitLab From 9fce1bc956c21dfe0f46be028f18c4d5057f2bd7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 16 Jul 2008 22:54:30 +0800 Subject: [PATCH 2271/2509] 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 --- drivers/pci/hotplug/pciehp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index d17233ae06f..e3a1e7e7dba 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; }; -- GitLab From e22146e610bb7aed63282148740ab1d1b91e1d90 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 16 Jul 2008 11:11:59 -0500 Subject: [PATCH 2272/2509] 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 --- arch/x86/mm/init_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 27de2435e00..306049edd55 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; -- GitLab From bd4bc3dbded9cd7b2bdca6bba1aecb4251a8039d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:05 +0200 Subject: [PATCH 2273/2509] 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 --- drivers/i2c/busses/i2c-amd756-s4882.c | 27 +++++++++++----------- drivers/i2c/busses/i2c-nforce2-s4985.c | 31 +++++++++++++------------- drivers/i2c/i2c-core.c | 4 ++++ 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 2f150e33c74..72872d1e63e 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 6a8995dfd0b..d1a4cbcf2aa 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 0a79f766101..7608df83d6d 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; -- GitLab From 68be3363740e4ac3b4309faebcdf8fe5bf62ed2f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:05 +0200 Subject: [PATCH 2274/2509] 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 --- drivers/i2c/chips/eeprom.c | 92 +++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 373ea8d8fe8..2c27193aeaa 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); -- GitLab From 8b77e6ac4911a79993e583ece719736a9e035b1d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: [PATCH 2275/2509] 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 --- drivers/i2c/chips/pcf8591.c | 94 ++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index db735379f22..16ce3e19377 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) { -- GitLab From 833bedb813689807385ae73175389c73a3f855c1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: [PATCH 2276/2509] 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 --- Documentation/i2c/chips/pcf8574 | 12 ++-- drivers/i2c/chips/pcf8574.c | 108 ++++++++++++++------------------ 2 files changed, 51 insertions(+), 69 deletions(-) diff --git a/Documentation/i2c/chips/pcf8574 b/Documentation/i2c/chips/pcf8574 index 5c1ad1376b6..235815c075f 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 1b3db2b3ada..6ec309894c8 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); -- GitLab From 97addff6def3f8e228a634fa017589f45c69de5c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: [PATCH 2277/2509] 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 --- Documentation/i2c/chips/pcf8575 | 9 ++-- drivers/i2c/chips/pcf8575.c | 96 ++++++++++++++------------------- 2 files changed, 43 insertions(+), 62 deletions(-) diff --git a/Documentation/i2c/chips/pcf8575 b/Documentation/i2c/chips/pcf8575 index 25f5698a61c..40b268eb276 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 3ea08ac0bfa..07fd7cb3c57 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); -- GitLab From 3d63430a26b91fe3daee0dd933f899c225e66daa Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: [PATCH 2278/2509] 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 --- Documentation/i2c/chips/pca9539 | 10 ++- drivers/i2c/chips/pca9539.c | 109 ++++++++++---------------------- 2 files changed, 42 insertions(+), 77 deletions(-) diff --git a/Documentation/i2c/chips/pca9539 b/Documentation/i2c/chips/pca9539 index 1d81c530c4a..6aff890088b 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 58ab7f26be2..270de4e56a8 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); -- GitLab From bd8d421f7ca9f8da3d820d28379d796500f69529 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: [PATCH 2279/2509] 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 --- Documentation/i2c/chips/max6875 | 2 +- drivers/i2c/chips/max6875.c | 120 +++++++++++++------------------- 2 files changed, 50 insertions(+), 72 deletions(-) diff --git a/Documentation/i2c/chips/max6875 b/Documentation/i2c/chips/max6875 index a0cd8af2f40..10ca43cd1a7 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 5a0285d8b6f..033d9d81ec8 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); -- GitLab From 61c91f7ded640bb2b340cc89d9ca3a3ca0229c74 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: [PATCH 2280/2509] 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 --- drivers/w1/masters/ds2482.c | 104 +++++++++++++++--------------------- 1 file changed, 44 insertions(+), 60 deletions(-) diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index 0fd5820d5c6..df52cb355f7 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; -- GitLab From 369932f6f840aedfbc717dd156bba7668a11d916 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: [PATCH 2281/2509] 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 --- drivers/hwmon/ad7418.c | 109 ++++++++++------------------------------- 1 file changed, 26 insertions(+), 83 deletions(-) diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index 466b9ee9279..f97b5b35687 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; } -- GitLab From 65817ed8d1376afff21019b5c0e0109e5a7d9cc0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: [PATCH 2282/2509] 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 --- drivers/hwmon/adm1021.c | 105 ++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index ecbf69484bf..b11e06f644b 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; } -- GitLab From 7dbafe021ba360bf25674a7e290d3e4a5c953981 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: [PATCH 2283/2509] 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 --- drivers/hwmon/adm1025.c | 101 +++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 1d76de7d75c..4db04d603ec 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; } -- GitLab From 57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: [PATCH 2284/2509] 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 --- drivers/hwmon/adm1026.c | 109 ++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 65 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 904c6ce9d83..7fe2441fc84 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; } -- GitLab From 9c97fb4d255fbf6713ee2d77dd8ed8ae770a7e49 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: [PATCH 2285/2509] 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 --- drivers/hwmon/adm1029.c | 97 +++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 2c6608d453c..ba84ca5923f 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; } -- GitLab From af200f881d2cbf3ba2f4c505fa1ae5cfef36f46a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: [PATCH 2286/2509] 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 --- drivers/hwmon/adm1031.c | 96 +++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 2bffcab7dc9..789441830cd 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; } -- GitLab From 7fae8283109e155467bc1c622178d3a475cdbddf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: [PATCH 2287/2509] 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 --- drivers/hwmon/adm9240.c | 93 ++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 149ef25252e..2444b15f2e9 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; } -- GitLab From 7347cb388e5aecffc4920bd5ea6a61e4a4690bae Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: [PATCH 2288/2509] 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 --- drivers/hwmon/ads7828.c | 89 ++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 51 deletions(-) diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 5c8b6e0ff47..5c39b4af1b2 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: -- GitLab From 008f1ca51e4a25ee3e34b8faa901dbeefaf0081a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: [PATCH 2289/2509] 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 --- drivers/hwmon/adt7470.c | 100 +++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 6b5325f33a2..d368d8f845e 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; } -- GitLab From eea54766c6e3f9850affa91061164aeb6bba44b6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: [PATCH 2290/2509] 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 --- drivers/hwmon/adt7473.c | 102 +++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 54 deletions(-) diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index 93dbf5e7ff8..ce4a7cb5a11 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; } -- GitLab From 063675b15608dfbb8404b3a19546d579bd039d02 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: [PATCH 2291/2509] 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 --- drivers/hwmon/asb100.c | 207 +++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 124 deletions(-) diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index fe2eea4d799..8a45a2e6ba8 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; } -- GitLab From 71163c7c36fa76bb5a72feca7fb685677444070a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: [PATCH 2292/2509] 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 --- drivers/hwmon/atxp1.c | 109 ++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 57 deletions(-) diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 01c17e387f0..d191118ba0c 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) -- GitLab From 70313eabfc63ce6aa89b9fa3074129e5c521568a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: [PATCH 2293/2509] 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 --- drivers/hwmon/ds1621.c | 99 ++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 5f300ffed65..7415381601c 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; -- GitLab From 935ada8c4481f9591caa1b88c83127c5931a8855 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: [PATCH 2294/2509] 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 --- drivers/hwmon/f75375s.c | 89 ++++++----------------------------------- 1 file changed, 12 insertions(+), 77 deletions(-) diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index dc1f30e432e..1692de36996 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); } -- GitLab From c2df1591df3ea83b4a5890a1131dd821ca07e761 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: [PATCH 2295/2509] 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 --- drivers/hwmon/fscher.c | 93 +++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index ed26b66e083..12c70e402cb 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; } -- GitLab From 40ac1994bf988dac05434f856c2a4fa24e22b2ea Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: [PATCH 2296/2509] 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 --- drivers/hwmon/fschmd.c | 112 +++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index bd89d270a5e..96717036893 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; } -- GitLab From b9e39b1b1b79d3e074ca79b63f548ac48c85ca98 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: [PATCH 2297/2509] 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 --- drivers/hwmon/fscpos.c | 94 ++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 00f48484e54..8a7bcf500b4 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; } -- GitLab From 95d80e7c834d8742da38e2b9d2f36dec36da03a6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: [PATCH 2298/2509] 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 --- drivers/hwmon/gl518sm.c | 99 +++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 33e9e8a8d1c..7820df45d77 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; } -- GitLab From a23a9fe1d4d725e1624635f49e9790ec32deffd0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: [PATCH 2299/2509] 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 --- drivers/hwmon/gl520sm.c | 91 +++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 8984ef14162..19616f2242b 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; } -- GitLab From d5957be2f1535b1a6c77eabba0781ec7245c5dea Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: [PATCH 2300/2509] 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 --- drivers/hwmon/lm63.c | 99 ++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 11628700808..3195a265f0e 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; } -- GitLab From a189dd62d328db7bf8ba68de6a948fdbc93dca25 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: [PATCH 2301/2509] 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 --- drivers/hwmon/lm77.c | 102 +++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 36d5a8c3ad8..866b401ab6e 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; } -- GitLab From 8c8bacc883610b672d3f08dc6ebf1f17e495f5b9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: [PATCH 2302/2509] 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 --- drivers/hwmon/lm80.c | 94 ++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 26c91c9d476..bcffc189940 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; -- GitLab From b6aacdcefac8ed60e77930b6e74129da6478e20e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: [PATCH 2303/2509] 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 --- drivers/hwmon/lm83.c | 104 ++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 55 deletions(-) diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 6a8642fa25f..e59e2d1f080 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; } -- GitLab From a888420af07b9a26b6d518328baa913fb704e950 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: [PATCH 2304/2509] 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 --- drivers/hwmon/lm87.c | 99 ++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index e1c183f0aae..21970f0d53a 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; } -- GitLab From 9b0e85269275159a1f9c3e4a5d254caf5211950b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: [PATCH 2305/2509] 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 --- drivers/hwmon/lm90.c | 119 +++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d1a3da3dd8e..c24fe36ac78 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; } -- GitLab From 910e8dcf16dd7afc08dc1791155cc69e07ca4183 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: [PATCH 2306/2509] 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 --- drivers/hwmon/lm92.c | 98 ++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 58 deletions(-) diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index c31942e0824..b2e00c5a7ee 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) -- GitLab From 70b724063f789a443aff1e1a6f0f04d971342116 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: [PATCH 2307/2509] 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 --- drivers/hwmon/lm93.c | 126 +++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 5e678f5c883..fc36cadf36f 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) -- GitLab From c6d3f6fa1b0b984991d6e2a261c7dd7f2685c7bd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: [PATCH 2308/2509] 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 --- drivers/hwmon/max1619.c | 101 +++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 57 deletions(-) diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 7e7267a0454..1ab1cacad59 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; } -- GitLab From 0d57abd5b87e2e82d8d2e8d5c9a3b56743ffa5ab Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: [PATCH 2309/2509] 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 --- drivers/hwmon/max6650.c | 102 ++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 52d528b76cc..f27af6a9da4 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) -- GitLab From 8fb597bb6ec80d53836229bf3576c7b848b909e3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: [PATCH 2310/2509] 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 --- drivers/hwmon/smsc47m192.c | 102 +++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 3c9db6598ba..8bb5cb532d4 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; -- GitLab From ccf37488322429bf8709f2227f3d48466add2b6b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: [PATCH 2311/2509] 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 --- drivers/hwmon/thmc50.c | 107 ++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 76a3859c3fb..3b01001108c 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); } -- GitLab From cb0c1af37996f3016e34e9c709e5f727646f7207 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: [PATCH 2312/2509] 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 --- drivers/hwmon/w83791d.c | 205 ++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 134 deletions(-) diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 85077c4c803..e4e91c9d480 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; } -- GitLab From 31d5d275a118527a2b9b0f68613428f176efbb8f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: [PATCH 2313/2509] 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 --- drivers/hwmon/w83792d.c | 214 ++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 142 deletions(-) diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 299629d47ed..cf94c5b0c87 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; } -- GitLab From a7f13a6ec40379fe2116c647ac8e569227ba8d4f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: [PATCH 2314/2509] 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 --- drivers/hwmon/w83793.c | 227 ++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 137 deletions(-) diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index ed3c019b78c..0a739f1c69b 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: -- GitLab From dc18a4184d6794e2e5c6f05142f3f8aaeeaee506 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:18 +0200 Subject: [PATCH 2315/2509] 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 --- drivers/hwmon/w83l785ts.c | 117 +++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 52e268e25da..ea295b9fc4f 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; } -- GitLab From 33468e7637c53b5516902422d66ca3d3fe64a9c3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:18 +0200 Subject: [PATCH 2316/2509] 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 --- drivers/hwmon/w83l786ng.c | 98 ++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 53 deletions(-) diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 41e22ddb568..badca769f35 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; -- GitLab From 84e0f3f6c1e26588fdcb9f1b0f99d0275229bc99 Mon Sep 17 00:00:00 2001 From: Dimitri Gorokhovik Date: Wed, 16 Jul 2008 20:33:34 +0200 Subject: [PATCH 2317/2509] 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 --- drivers/ide/pci/it821x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 6ab04115286..cbf64720299 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, }; /** -- GitLab From 0b6abc17700a7843b165c677da0ac94522f83083 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: [PATCH 2318/2509] 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 --- drivers/ide/ide-cd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d9984715718..d6667c36568 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 */ -- GitLab From e5318b531b008c79d2a0c0df06a7b8628da38e2f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: [PATCH 2319/2509] 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 --- drivers/ide/ide-cd.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d6667c36568..e12d6027821 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; -- GitLab From 96b1dfe8fe02e35f017c885b11f0beb10ff4f316 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 20 Jun 2008 20:53:35 +0200 Subject: [PATCH 2320/2509] 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 --- drivers/ide/Kconfig | 7 --- drivers/ide/arm/Makefile | 1 - drivers/ide/arm/bast-ide.c | 90 -------------------------------------- 3 files changed, 98 deletions(-) delete mode 100644 drivers/ide/arm/bast-ide.c diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cf707c8f08d..cd08dba8261 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 936e7b0237f..5bc26053afa 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 8e8c28104b4..00000000000 --- 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"); -- GitLab From e4e8d02f56f5c0cefc6713384629e068193d706a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: [PATCH 2321/2509] ide: remove needless includes from ide-lib.c Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-lib.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 47af80df687..7e053d21773 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" }; -- GitLab From f0ffc9872e972e9d9fe8f7ae577ff046dbdba51b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: [PATCH 2322/2509] 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 --- drivers/ide/ide-timing.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 2e91c5870b4..a20c4cbbfcd 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 }, -- GitLab From 71d5161426c26742ba053fe93637559cbe2cea37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: [PATCH 2323/2509] 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 --- drivers/ide/ide-timing.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index a20c4cbbfcd..ebe884d7688 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; -- GitLab From 3be53f3f213223f50d8e29b5e1869685bf040a1e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: [PATCH 2324/2509] 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 --- drivers/ide/ide-timing.h | 23 ----------------------- include/linux/ide.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index ebe884d7688..724879910ac 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 ac4eeb2932e..81c6ea436be 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 */ -- GitLab From bd887f72d2a28a8202519e67fd9ed93ee3c4e78d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: [PATCH 2325/2509] 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 --- drivers/ide/ide-timing.h | 24 +++++++----------------- drivers/ide/pci/cs5535.c | 4 +--- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 724879910ac..a401d8f82b5 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 99fe91a191b..2a2cb491190 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; -- GitLab From 2c139e7a7152f66ff93b173f8770c94ea53a691e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: [PATCH 2326/2509] 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 --- drivers/ide/ide-timing.h | 93 +++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index a401d8f82b5..98e05f54545 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; -- GitLab From f06ab3402aa2d6de060442c1053ea10b24b65076 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: [PATCH 2327/2509] 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 --- drivers/ide/Kconfig | 7 ++++ drivers/ide/Makefile | 1 + drivers/ide/arm/palm_bk3710.c | 2 -- drivers/ide/{ide-timing.h => ide-timings.c} | 38 ++++++++++----------- drivers/ide/pci/amd74xx.c | 2 -- drivers/ide/pci/cs5535.c | 2 -- drivers/ide/pci/sis5513.c | 3 -- drivers/ide/pci/via82cxxx.c | 2 -- drivers/ide/ppc/pmac.c | 2 -- include/linux/ide.h | 5 +++ 10 files changed, 32 insertions(+), 32 deletions(-) rename drivers/ide/{ide-timing.h => ide-timings.c} (92%) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cd08dba8261..994b6d39b55 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 a2b3f84d710..cb1350684c9 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 3839f572298..9b8a45d2cf1 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-timings.c similarity index 92% rename from drivers/ide/ide-timing.h rename to drivers/ide/ide-timings.c index 98e05f54545..ebef6d4e3f6 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timings.c @@ -1,6 +1,3 @@ -#ifndef _IDE_TIMING_H -#define _IDE_TIMING_H - /* * Copyright (c) 1999-2001 Vojtech Pavlik * @@ -25,6 +22,8 @@ #include #include +#include +#include /* * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). @@ -65,6 +64,17 @@ static struct ide_timing ide_timing[] = { { 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) @@ -81,8 +91,8 @@ static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, 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) +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); @@ -101,19 +111,10 @@ static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, if (what & IDE_TIMING_UDMA) m->udma = max(a->udma, b->udma); } +EXPORT_SYMBOL_GPL(ide_timing_merge); -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) +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; @@ -179,5 +180,4 @@ static int ide_timing_compute(ide_drive_t *drive, u8 speed, return 0; } - -#endif +EXPORT_SYMBOL_GPL(ide_timing_compute); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index ad222206a42..0bfcdd0e77b 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 2a2cb491190..dc97c48623f 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 e127eb25ab6..2389945ca95 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 3ed9728abd2..e47384c70c4 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 dcb2c466bb9..5b91d23269d 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 81c6ea436be..057001f6b1d 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 */ -- GitLab From cc57ccc03d2a9b5622300f4b59fc8b54408c6e24 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: [PATCH 2328/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/legacy/ali14xx.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 994b6d39b55..e9afafd55cd 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 052125fafcf..4ec19737f3c 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) { -- GitLab From b32b76f72df17de891181b47e714f9f897bb62a1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: [PATCH 2329/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/legacy/ht6560b.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e9afafd55cd..615e0bc0184 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 dd6dfb32e85..bd2f579946f 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 */ -- GitLab From 2feecface7fd62be75bd4961324dc279a04bef22 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: [PATCH 2330/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/legacy/qd65xx.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 615e0bc0184..86db707ad6c 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 51dba82f881..63f6c31d16e 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; } } -- GitLab From 288911af1209f5aa6119c9ec6d5a9bdb16a385b5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: [PATCH 2331/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/pci/alim15x3.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 86db707ad6c..cadce92047f 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 f2de00adf14..80d19c0eb78 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; -- GitLab From 17b500de0ad79a306a0cd8acfe9a9f086ad28b4c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2332/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/pci/cmd640.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cadce92047f..e072bdea907 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 cd1ba14984a..baa26a26709 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); -- GitLab From 86a0e12fcb590a6a84b90ae00e6d6564ce770749 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2333/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/pci/cmd64x.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e072bdea907..d5526d3af62 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 ca4774aa27e..cfa784bacf4 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)); /* -- GitLab From 713a590dea9a61e84f2837e75c5e9429d95908b5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2334/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/pci/cy82c693.c | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index d5526d3af62..7446db64906 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 8c534afcb6c..e14ad5530fa 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); -- GitLab From 3f847571a1cf845a338bcd352f31240b3615f40d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2335/2509] 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 --- drivers/ide/Kconfig | 1 + drivers/ide/pci/sl82c105.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 7446db64906..5f4d6ea379f 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 ce84fa045d3..6efbde29717 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) -- GitLab From b96f7384646519da54ad50bfad8d53b915b70cb3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2336/2509] 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 --- drivers/ide/ppc/mpc8xx.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c index 236f9c38e51..33bc699814d 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 -- GitLab From 8a97206e31dc2e2f8f9b4d97e234b5c701fe9894 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: [PATCH 2337/2509] 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 --- drivers/ide/ppc/pmac.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 5b91d23269d..cfa103a51b3 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); -- GitLab From c9d6c1a2379373219bb3271bdcbdc0ab2edf349d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: [PATCH 2338/2509] 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 --- drivers/ide/ide-lib.c | 23 ----------------------- drivers/ide/ide-timings.c | 22 ++++++++++++++++++++++ include/linux/ide.h | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 7e053d21773..efa5bfa64d0 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 ebef6d4e3f6..8c2f8327f48 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 057001f6b1d..3899c761b30 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]; -- GitLab From 3e153cfb5e38ae237ff27a10a833946ac95db8a4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: [PATCH 2339/2509] ide: remove no longer used ide_pio_timings[] Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-lib.c | 17 ----------------- include/linux/ide.h | 8 -------- 2 files changed, 25 deletions(-) diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index efa5bfa64d0..3e12f229bd5 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -75,23 +75,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) return min(speed, mode); } -/* - * 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 diff --git a/include/linux/ide.h b/include/linux/ide.h index 3899c761b30..4e44525fa5c 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); -- GitLab From 9ad540937554a3779c5fe7af13aa390b1d2aeb3e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: [PATCH 2340/2509] 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 --- drivers/ide/Makefile | 3 +- drivers/ide/ide-lib.c | 96 --------------------------------- drivers/ide/ide-pio-blacklist.c | 94 ++++++++++++++++++++++++++++++++ include/linux/ide.h | 2 + 4 files changed, 98 insertions(+), 97 deletions(-) create mode 100644 drivers/ide/ide-pio-blacklist.c diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index cb1350684c9..8605536ea18 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 3e12f229bd5..13af72f09ec 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 00000000000..a8c2c8f8660 --- /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 4e44525fa5c..535c439fd8f 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); -- GitLab From 256c5f8eef7b9a8c8a85c15c58cda9df455f947e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: [PATCH 2341/2509] 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 --- drivers/ide/arm/palm_bk3710.c | 1 - drivers/ide/h8300/ide-h8300.c | 1 - drivers/ide/ide-pnp.c | 1 - drivers/ide/ide-probe.c | 10 +++++++--- drivers/ide/ide.c | 15 --------------- drivers/ide/legacy/buddha.c | 1 - drivers/ide/legacy/falconide.c | 1 - drivers/ide/legacy/gayle.c | 1 - drivers/ide/legacy/ide-cs.c | 1 - drivers/ide/legacy/macide.c | 1 - drivers/ide/legacy/q40ide.c | 1 - drivers/ide/pci/delkin_cb.c | 1 - 12 files changed, 7 insertions(+), 28 deletions(-) diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 9b8a45d2cf1..c79b85b6e4a 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 ae37ee58bae..dfce105bae6 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 adbd0178416..fc1e10c9d1c 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 d21e51a02c3..592d424412e 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 2b8453510e0..32d8ee281d5 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 9a1d27ef3f8..0497e7f85b0 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 af11028b479..129a812bb57 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 b78941680c3..7e74b20202d 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 8dbf4d9b644..7c69608154c 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 2e84290d0bc..0a6195bcfed 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 8ff6e2d2083..9c2b9d078f6 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 af0f30051d5..0106e2a2df7 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; -- GitLab From 63b51c6d1d63276fd320615c042f1ff5d94ebab8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2342/2509] ide: make ide_hwifs[] static Move ide_hwifs[] from ide.c to ide-probe.c and make it static. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 2 ++ drivers/ide/ide.c | 2 -- include/linux/ide.h | 12 ------------ 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 592d424412e..97dda05914a 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 32d8ee281d5..b7855a13f0e 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 535c439fd8f..15d5668198a 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; -- GitLab From c56c5648a3bd15ff14c50f284b261140cd5b5472 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2343/2509] 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 --- drivers/ide/ide.c | 3 ++- drivers/ide/mips/au1xxx-ide.c | 2 -- drivers/ide/pci/scc_pata.c | 1 - drivers/ide/pci/sgiioc4.c | 2 -- drivers/ide/ppc/pmac.c | 6 ++---- drivers/ide/setup-pci.c | 2 -- include/linux/ide.h | 2 +- 7 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index b7855a13f0e..9240888e5ef 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 1a6c27b3249..08c46c36b7e 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 1584ebb6a18..71bff3131b9 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 24513e3dcd6..af91cc52578 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 cfa103a51b3..93fb9067c04 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 abcfb1739d4..3dea5a59626 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 15d5668198a..a6a2eccb652 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); -- GitLab From a536f326a2223c951818e199e23847c2ac5e483b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2344/2509] 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 --- drivers/ide/mips/au1xxx-ide.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 08c46c36b7e..48d57cae63c 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; -- GitLab From f333f92bf9040fb63d13c184295629c7a0ff449f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2345/2509] 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 --- drivers/ide/legacy/ide-4drives.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index ecae916a338..5cd6ce537ee 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; } -- GitLab From dccdf527379dc2fe8a4efc5c75601d1d4035a750 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2346/2509] 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 --- drivers/ide/legacy/ide-cs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 7c69608154c..fc53dcfbfe3 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; -- GitLab From 26839f09ca2d0f4239e546cd912bc9f4694f3c5e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: [PATCH 2347/2509] 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 --- drivers/ide/arm/icside.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 061456914ca..74395804427 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: -- GitLab From b25afdf1336237fb0e4021eb35744e577e19bd14 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2348/2509] 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 --- drivers/ide/arm/icside.c | 72 +++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 74395804427..c8d86006032 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; -- GitLab From 01397012b3129147890bb116431d5a794dfc3990 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2349/2509] sgiioc4: use driver name for resource allocation Cc: Jeremy Higdon Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sgiioc4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index af91cc52578..dd0d0f73ab1 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; } -- GitLab From c1da678b5b4d8ce7836ed1ded80109d1db37efe0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2350/2509] 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 --- drivers/ide/setup-pci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 3dea5a59626..166211f53f1 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 " -- GitLab From e48905e9cfffd21861c3521d828ae992a53aac67 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2351/2509] 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 --- drivers/ide/mips/swarm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 52fee3d2771..57a0138d0db 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); -- GitLab From ba1d0de70d64e68f0e035f00dbb041c1e05b49c9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2352/2509] 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 --- drivers/ide/Kconfig | 40 -- drivers/ide/ppc/Makefile | 1 - drivers/ide/ppc/mpc8xx.c | 844 --------------------------------------- 3 files changed, 885 deletions(-) delete mode 100644 drivers/ide/ppc/mpc8xx.c diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5f4d6ea379f..21511d47d92 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 65af5848b28..74e52adcdf4 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 33bc699814d..00000000000 --- 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"); -- GitLab From a698400a1556cf9f0376d1a41e536973dd5c4747 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: [PATCH 2353/2509] 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 --- drivers/ide/pci/cmd640.c | 51 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index baa26a26709..ab7d7274d8b 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); -- GitLab From e6d95bd14928926d6658b5e4ace905e8b83ed27a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2354/2509] 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 --- drivers/ide/ide-probe.c | 6 +++--- drivers/ide/legacy/ht6560b.c | 8 ++++---- drivers/ide/legacy/ide-4drives.c | 10 ++++------ drivers/ide/legacy/qd65xx.c | 16 ++++++++-------- include/linux/ide.h | 4 ++-- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 97dda05914a..c5dc1884930 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 bd2f579946f..7bc8fd59ea9 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 5cd6ce537ee..89c8ff0a4d0 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 63f6c31d16e..2338f344ea2 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 a6a2eccb652..f9cbe9350ca 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 */ -- GitLab From b48c89a9699f451e4e236fa7313461281c00e69b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2355/2509] 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 --- drivers/ide/pci/cmd640.c | 72 +++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index ab7d7274d8b..1ad1e23e310 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 -- GitLab From 9a5ae1faaaf43933dee48c223b193d5e1c4b8b0c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2356/2509] 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 --- drivers/ide/arm/rapide.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index 1747b235877..bb081ad53f3 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; -- GitLab From f81eb80bbb949f9498980c785ef7dd4c994a4909 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2357/2509] 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 --- drivers/ide/h8300/ide-h8300.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index dfce105bae6..ff6a98afefb 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; -- GitLab From 7b60fa16ca50b0f8cb9d007faee0dff71b397fb8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2358/2509] 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 --- drivers/ide/legacy/ide_platform.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index d3bc3f24e05..a249562b34b 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); -- GitLab From eb3aff5530d22eb4be0a99c9d39c9ffde7b9891a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: [PATCH 2359/2509] 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 --- drivers/ide/h8300/ide-h8300.c | 8 ++++---- drivers/ide/ide-probe.c | 3 +++ drivers/ide/mips/swarm.c | 7 +++---- drivers/ide/pci/scc_pata.c | 7 ++----- drivers/ide/pci/sgiioc4.c | 8 +++----- drivers/ide/setup-pci.c | 5 +---- 6 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index ff6a98afefb..c445298f7eb 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 c5dc1884930..235ebdb29b2 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 57a0138d0db..bae92acea34 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 71bff3131b9..789c66dfbde 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 dd0d0f73ab1..be73acb2080 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 166211f53f1..4321d20fe87 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; -- GitLab From 740c397cc64272917a4c4c283649579d2044a836 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: [PATCH 2360/2509] ide-h8300: print driver banner message early Print driver banner message early and without interface number. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/h8300/ide-h8300.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index c445298f7eb..20fad6d542c 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; -- GitLab From e193c3e141df4b536ed077b29c83a96768333607 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: [PATCH 2361/2509] ide-pnp: print driver banner message early Print driver banner message early and without interface number. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-pnp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index fc1e10c9d1c..03f2ef5470a 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); -- GitLab From 07fe69d5d0b6e476cecaf75e81c0c6093571087b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: [PATCH 2362/2509] 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 --- drivers/ide/ide-taskfile.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index cf55a48a7dd..994a5161c04 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); -- GitLab From 605cfe8270cb182f494575c5a608404bb19fdfc5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: [PATCH 2363/2509] 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 --- drivers/ide/ide-taskfile.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 994a5161c04..0d0bf292c41 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; } -- GitLab From 61729415e64a1149d4eb36c3fac26a28728ad1d7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: [PATCH 2364/2509] ide: remove needless includes from ide.c Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9240888e5ef..90ae00d4aaf 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 */ -- GitLab From ad15e9fc8913b704978ffdda7d1f31c79ed6814d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2365/2509] 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 --- drivers/ide/ide-taskfile.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0d0bf292c41..1fbdb746dc8 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 -- GitLab From ff23712e791fd80f3b088d5e1c5733c0944cfe64 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2366/2509] ide: remove needless includes from setup-pci.c (take 2) v2: * sparc build fix. (From Stephen Rothwell) Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/setup-pci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 4321d20fe87..65fc08b6b6d 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 -- GitLab From 47bc7e7425d198ad1f8c4597b0bf28619fcce0fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2367/2509] 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 --- drivers/ide/arm/rapide.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index bb081ad53f3..43057e0303c 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); -- GitLab From 67717e224181527987cce800fa2ddb5c8c1e9315 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2368/2509] 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 --- drivers/ide/arm/icside.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index c8d86006032..52f58c88578 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; -- GitLab From cb8ea0929c9cb899d61c4e155aace0b34d8cffe3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2369/2509] 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 --- drivers/ide/mips/swarm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index bae92acea34..9f1212cc4ae 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 = { -- GitLab From ce30e4015954e281f682aa8d158a47885d8e1262 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: [PATCH 2370/2509] 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 --- drivers/ide/pci/sgiioc4.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index be73acb2080..c79ff5b4108 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 -- GitLab From af6765ce9f535f20e6f9975269660fe49594745a Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: [PATCH 2371/2509] 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 --- drivers/ide/ide-cd.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index e12d6027821..eb4b27548ca 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); -- GitLab From ae8789f034ffa077105575817ec0cc581fd18d83 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: [PATCH 2372/2509] 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 --- drivers/ide/ide-cd.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index eb4b27548ca..789b19cf5e5 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -598,28 +598,6 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, return ide_started; } -/* - * 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 @@ -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; -- GitLab From ab9d6e3374d938cf3d941fbed5ba32a19ad263b8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: [PATCH 2373/2509] 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 --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 789b19cf5e5..6ade498cd2f 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; } -- GitLab From 8ea1d17b962c35401fe26428e25c4652023e2652 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: [PATCH 2374/2509] 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 --- drivers/ide/ide-cd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 6ade498cd2f..ff98222ece0 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; -- GitLab From 99384aeafe3a78d8a2e66b09b67aa6a219cd7897 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: [PATCH 2375/2509] 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 --- drivers/ide/ide-cd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ff98222ece0..a9be4bf87dd 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, -- GitLab From b6ca440a8ff15e12478ea6f026a52970e7a0c54c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2376/2509] 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 --- drivers/ide/ide-cd.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index a9be4bf87dd..b61ce5ee08e 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); } -- GitLab From 4b01fcbbe69bba34a8494fca6376ac0804f0f51d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2377/2509] 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 --- drivers/ide/ide-cd.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index b61ce5ee08e..66d82c1b16e 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; -- GitLab From e529c6087a845e64a6a36a2d17b8754b20bc7c0d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2378/2509] 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 --- drivers/ide/ide-cd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 66d82c1b16e..275d5ba1202 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; -- GitLab From 90eb808e0fd3cbda8a8b085238930c533f603642 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2379/2509] 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 --- drivers/ide/ide-cd.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 275d5ba1202..9e593cebc00 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) || -- GitLab From 7fcebda501681080a242733b8db3f09f5ccb5d3f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2380/2509] 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 --- drivers/ide/ide-cd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 9e593cebc00..2b3c69d1f53 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. * -- GitLab From c96a7df8dba5800c03b0f1edd87b2f3d0473a119 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: [PATCH 2381/2509] 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 --- drivers/ide/ide-floppy.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index b3689437269..df19ede7388 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); -- GitLab From 68dc3575e064a5655cbd656fbf32d6ceeb85ac9e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2382/2509] 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 --- drivers/ide/ide-floppy.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index df19ede7388..00948c39822 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; -- GitLab From 85ae98a3dff2da860a4f8f9e4a0de69ad82ce633 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2383/2509] ide: endian annotations in ide-floppy.c Signed-off-by: Harvey Harrison Cc: Al Viro Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-floppy.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 00948c39822..c7e4433fcbc 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); -- GitLab From ffa793f9bb5b563edb4cacc43a4d6677eec0e36b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2384/2509] 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 --- drivers/ide/Kconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 21511d47d92..39b95f9c2ad 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 -- GitLab From 01c22bfc30a3f40fed08cfd2779348edcb6c5e53 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2385/2509] 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 --- drivers/ide/Makefile | 1 - drivers/ide/legacy/hd.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 8605536ea18..39e99ace5cd 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 abdedf56643..00b695652b2 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); -- GitLab From 453ea3ed0b3e8ad67d4ee9d2fccf3d95a3e1f709 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2386/2509] 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 --- drivers/block/Kconfig | 24 ++++++++++++++++++++++++ drivers/block/Makefile | 1 + drivers/{ide/legacy => block}/hd.c | 0 drivers/ide/Kconfig | 23 ----------------------- drivers/ide/Makefile | 5 ----- 5 files changed, 25 insertions(+), 28 deletions(-) rename drivers/{ide/legacy => block}/hd.c (100%) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 0d1d2133d9b..c3909743c48 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 5e584306be9..204332b2957 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/ide/legacy/hd.c b/drivers/block/hd.c similarity index 100% rename from drivers/ide/legacy/hd.c rename to drivers/block/hd.c diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 39b95f9c2ad..15b09b89588 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 39e99ace5cd..5d414e301a5 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 -- GitLab From f327c1c33f4882c70f29ff3a9ff7c55c1951d1f6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: [PATCH 2387/2509] 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 --- drivers/block/Kconfig | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index c3909743c48..61ad8d639ba 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 -- GitLab From 72a3d651b2fe341a8ae2ca164c395aa3007350cd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: [PATCH 2388/2509] 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 --- drivers/block/hd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 00b695652b2..682243bf2e4 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -37,7 +37,6 @@ #include #include #include -#include /* CMOS defines */ #include #include #include -- GitLab From 79e36a9f54aaf4a52eb2d9520953aa3960e99294 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: [PATCH 2389/2509] 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 --- drivers/ide/ide-io.c | 23 ++++++++++++++++++++++- drivers/ide/ide-iops.c | 18 +++++++++++++----- drivers/ide/ide.c | 41 +++++++++++++++-------------------------- include/linux/ide.h | 6 ++++++ 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 28057747c1f..2b33c129740 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 80ad4f234f3..96f63eb1209 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 90ae00d4aaf..1ec983b0051 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 f9cbe9350ca..021710cc1b1 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -138,6 +138,12 @@ struct ide_io_ports { #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ #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 */ -- GitLab From 3ef5eb424ebf0cd981192a416358fd707a9f959b Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: [PATCH 2390/2509] 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 --- drivers/ide/ide-cd.c | 1 - drivers/ide/ide-disk.c | 1 - drivers/ide/ide-floppy.c | 1 - drivers/ide/ide-io.c | 49 ---------------------------------------- drivers/ide/ide-tape.c | 1 - drivers/scsi/ide-scsi.c | 14 ------------ include/linux/ide.h | 7 ------ 7 files changed, 74 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 2b3c69d1f53..6e29dd53209 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 5f49a4ae9dd..3a2e80237c1 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 c7e4433fcbc..011d72011cc 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 2b33c129740..661b75a89d4 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 f9cf1670e4e..b711ab96e28 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 683bce375c7..f843c1383a4 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 021710cc1b1..4726126f5a5 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); -- GitLab From bb7ee9b1ec15358af870a81b0c6a03af29417f99 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: [PATCH 2391/2509] 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 --- Documentation/ioctl/hdio.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt index c19efdeace2..44d283d6b13 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. -- GitLab From 64a8f00ff19508b3962c8a932375dbae88bee4d6 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: [PATCH 2392/2509] 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 --- Documentation/ioctl/hdio.txt | 2 ++ drivers/ide/ide-iops.c | 18 +++++++++++------- drivers/ide/ide.c | 10 ++++++---- drivers/ide/pci/siimage.c | 3 +-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt index 44d283d6b13..91a6ecbae0b 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 96f63eb1209..44aaec256a3 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 1ec983b0051..d4a6b102a77 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 b75e9bb390a..6e9d7655d89 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; } } -- GitLab From bef5b54bd7bf8117c75cb943d64549134c6d9a1f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 16 Jul 2008 13:02:24 +0100 Subject: [PATCH 2393/2509] 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 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8a2a275be30..1564577bdc5 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 -- GitLab From e3621ee633810be1079d0fa65ac2c904f53b73fa Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 16 Jul 2008 08:39:12 -0500 Subject: [PATCH 2394/2509] 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 --- arch/powerpc/platforms/82xx/ep8248e.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index d5770fdf7f0..373e993a5ed 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; } -- GitLab From 3c3622dcb64c76c9abd2e468f802db9ba523421c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 16 Jul 2008 08:52:00 -0500 Subject: [PATCH 2395/2509] 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 --- fs/compat_ioctl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 97dba0d9234..c54eaab71a1 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) -- GitLab From 26d46867b7d27f68a446b073dac7817721ae4c8f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:35:48 -0400 Subject: [PATCH 2396/2509] 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 --- drivers/acpi/scan.c | 56 ++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 6d85289f1c1..9a84ed250d9 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; } -- GitLab From b62b8ef906cdf7115af579ce7378886ce3e0ce00 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:35:56 -0400 Subject: [PATCH 2397/2509] 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 --- drivers/acpi/processor_core.c | 6 +++--- kernel/cpu.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9dd0fa93b9e..1c0008edccd 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 b11f06dc149..cfb1d43ab80 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 */ -- GitLab From 9f1eb99c757939b0b1783f926130993e9c298bae Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:36:07 -0400 Subject: [PATCH 2398/2509] 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 --- drivers/acpi/processor_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 1c0008edccd..feddc8ed870 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) { -- GitLab From 5411552c707f4b7387ad63141ef3a559e7488091 Mon Sep 17 00:00:00 2001 From: Cezary Jackiewicz Date: Mon, 9 Jun 2008 16:22:22 -0700 Subject: [PATCH 2399/2509] 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 --- MAINTAINERS | 5 + drivers/misc/Kconfig | 17 ++ drivers/misc/Makefile | 5 +- drivers/misc/compal-laptop.c | 437 +++++++++++++++++++++++++++++++++++ 4 files changed, 462 insertions(+), 2 deletions(-) create mode 100644 drivers/misc/compal-laptop.c diff --git a/MAINTAINERS b/MAINTAINERS index ee1c56a2075..2bfde032630 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 636af286230..7fce0da8654 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 1952875a272..a6dac6a2e7e 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 00000000000..0c1f5875fbb --- /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:*"); -- GitLab From 706546d02384b64e083bd9130c56eaa599c66038 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Mon, 9 Jun 2008 16:22:23 -0700 Subject: [PATCH 2400/2509] 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 --- drivers/acpi/processor_core.c | 20 +++++++++----------- drivers/acpi/processor_idle.c | 8 ++++---- drivers/acpi/processor_perflib.c | 18 +++++++++--------- drivers/acpi/processor_throttling.c | 14 +++++++------- include/acpi/processor.h | 2 +- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index feddc8ed870..9a803f85ccf 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 4976e5db2b3..0fc310e7dfd 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 d80b2d1441a..b4749969c6b 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 bb06738860c..8728782aad3 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 06ebb6ef72a..3795590e152 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); -- GitLab From 20b937343e55c16e37b1a4ad2176760b4a11002c Mon Sep 17 00:00:00 2001 From: Jonathan Woithe Date: Wed, 11 Jun 2008 10:14:56 +0930 Subject: [PATCH 2401/2509] 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 --- MAINTAINERS | 6 + drivers/misc/Kconfig | 13 +- drivers/misc/fujitsu-laptop.c | 825 +++++++++++++++++++++++++++++++--- 3 files changed, 792 insertions(+), 52 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2bfde032630..ec5c8ee3090 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 7fce0da8654..0551d95a749 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 6d14e8fe153..7a1ef6c262d 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); -- GitLab From 74523c901342a773ddd9f14c14539ec3d4197ecf Mon Sep 17 00:00:00 2001 From: Alok N Kataria Date: Fri, 13 Jun 2008 12:54:24 -0400 Subject: [PATCH 2402/2509] 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 --- drivers/acpi/scan.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9a84ed250d9..5b049cd7955 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; } -- GitLab From 6594d87ebd8371f4b67f7ab4b68f172b139b78d6 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Sat, 14 Jun 2008 00:52:06 -0400 Subject: [PATCH 2403/2509] 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 --- drivers/acpi/fan.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 6cf10cbc1ee..55c17afbe66 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)); -- GitLab From 3d532d5e3882c1387a2722df2a368c4a9224b12f Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Sat, 14 Jun 2008 00:54:37 -0400 Subject: [PATCH 2404/2509] 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 --- drivers/acpi/processor_throttling.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 8728782aad3..53345dbc502 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; -- GitLab From 12b2b34e240a24bdbb2fdacf26a54b24ebf1ed81 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Jun 2008 09:43:41 -0700 Subject: [PATCH 2405/2509] 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 --- drivers/acpi/processor_throttling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 53345dbc502..0622ace0522 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; -- GitLab From 87dc5e3218ba3d7a9293f9113f58455747a233ac Mon Sep 17 00:00:00 2001 From: Cezary Jackiewicz Date: Thu, 12 Jun 2008 22:08:59 +0200 Subject: [PATCH 2406/2509] compal-laptop: remove unnecessary lcd_level attribute Signed-off-by: Cezary Jackiewicz Signed-off-by: Len Brown Signed-off-by: Andi Kleen --- drivers/misc/compal-laptop.c | 37 ++---------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c index 0c1f5875fbb..344b790a625 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, -- GitLab From e38e8a0743b0e996a8a3fbea8908fe75a84f02c7 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 13 Jun 2008 08:28:55 +0800 Subject: [PATCH 2407/2509] 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 --- drivers/acpi/events/evgpe.c | 18 ++++++++++--- drivers/acpi/hardware/hwgpe.c | 50 ++++++++++++++++++++++++++++++++++- include/acpi/achware.h | 2 ++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index 5354be44f87..e0339d4139a 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 14bc4f456ae..58347d6c43f 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -53,6 +53,54 @@ static acpi_status acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block); +/****************************************************************************** + * + * 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 @@ -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 d4fb9bbc903..45e985961f4 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); -- GitLab From 47c00d2bc2ef2cf8a608688144fe2093a2aa9507 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 20 Jun 2008 13:56:56 +0200 Subject: [PATCH 2408/2509] 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 --- include/acpi/aclocal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index c5cdc32ac2f..62d7468ed3f 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", -- GitLab From 141094612d2606395a7b9e8658d10ef5c487cf97 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 25 Jun 2008 19:25:47 +0300 Subject: [PATCH 2409/2509] 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 --- drivers/misc/eeepc-laptop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c index 6d727609097..9e8d79e7e9f 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, -- GitLab From a0bbaf83311cd995136c9047f174d79c1075ee2d Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:08 +0100 Subject: [PATCH 2410/2509] 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 --- Documentation/laptops/acer-wmi.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt index 79b7dbd2214..69b5dd4e5a5 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 ********* -- GitLab From 9991d9f2bc75dc8735932240b67432d4073b8f60 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:22 +0100 Subject: [PATCH 2411/2509] 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 --- drivers/misc/acer-wmi.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index dd13a374992..b82ff25a7b5 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, }; @@ -208,6 +212,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", @@ -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"); -- GitLab From f2b585b4a31731b17b9769eae523986fa7fddcde Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:27 +0100 Subject: [PATCH 2412/2509] 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 --- drivers/misc/acer-wmi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index b82ff25a7b5..e35825f7e7b 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; } -- GitLab From 6f061ab5e55d7fe6ce0c36e8954f56f0d95348fb Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:38 +0100 Subject: [PATCH 2413/2509] 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 --- drivers/misc/acer-wmi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index e35825f7e7b..5b7c5fcd5af 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, @@ -321,6 +325,15 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .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", @@ -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) -- GitLab From 5753dd539a86d8fc40a25e1a2cd1005a6525f083 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:48 +0100 Subject: [PATCH 2414/2509] 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 --- drivers/misc/acer-wmi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index 5b7c5fcd5af..dd0b8d8b5bd 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; -- GitLab From 81143522aa823036c4aa35bdd3b2e41966cf6e15 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:53 +0100 Subject: [PATCH 2415/2509] 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 --- drivers/misc/acer-wmi.c | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index dd0b8d8b5bd..d8b8574e303 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 */ @@ -955,6 +965,28 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr, 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 */ @@ -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(); -- GitLab From 860f0c6b3dcaa455894f690647442dc97cab19c8 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:58 +0100 Subject: [PATCH 2416/2509] 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 --- drivers/misc/acer-wmi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index d8b8574e303..e7a3fe508df 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(); -- GitLab From d1857056904d5f313f11184fcfa624652ff9620a Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 20 Jun 2008 15:39:09 +0200 Subject: [PATCH 2417/2509] 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 --- drivers/acpi/glue.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 9b227d4dc9c..6d18ca34b6a 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void) { struct device *dev = get_rtc_dev(); + if (acpi_disabled) + return 0; + if (acpi_disabled) return 0; -- GitLab From cc7e51666d82aedfd6b9a033ca1a10d71c21f1ca Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 24 Jun 2008 22:57:12 -0400 Subject: [PATCH 2418/2509] dock: bay: Don't call acpi_walk_namespace() when ACPI is disabled. Signed-off-by: Len Brown Signed-off-by: Andi Kleen --- drivers/acpi/bay.c | 3 +++ drivers/acpi/dock.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index 61b6c5beb2d..e6caf5d42e0 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c @@ -377,6 +377,9 @@ static int __init bay_init(void) INIT_LIST_HEAD(&drive_bays); + if (acpi_disabled) + return -ENODEV; + if (acpi_disabled) return -ENODEV; diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bb7c51f712b..1e872e79db3 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -917,6 +917,9 @@ static int __init dock_init(void) dock_station = NULL; + if (acpi_disabled) + return 0; + if (acpi_disabled) return 0; -- GitLab From 2fe2de5f6c283a7d2a82c1b99a19012079cee555 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 5 Jun 2008 01:15:40 +0200 Subject: [PATCH 2419/2509] 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 --- drivers/acpi/sleep/main.c | 8 ++++---- drivers/pci/pci-acpi.c | 3 +-- drivers/pnp/pnpacpi/core.c | 4 +--- include/acpi/acpi_bus.h | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 495c63a3e0a..b45806d7728 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 9d6fc8e6285..caabf0573c3 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 50902773bea..c1b9ea34977 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 2f1c68c7a72..db90a74f871 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; -- GitLab From a80a6da145bab8ee77af304961fc926de7a8ac84 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 5 Jun 2008 01:16:37 +0200 Subject: [PATCH 2420/2509] 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 --- drivers/pci/pci-acpi.c | 3 +-- drivers/pci/pci.c | 4 ++-- drivers/pci/pci.h | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index caabf0573c3..dab9d471914 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 e4548ab2a93..75c60239cad 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 00408c97e5f..312daff834b 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); -- GitLab From 741438b5008791327d2183cebcd7ac9cfad64ec6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 5 Jun 2008 01:17:28 +0200 Subject: [PATCH 2421/2509] 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 --- drivers/acpi/sleep/main.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index b45806d7728..244e352f766 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) -- GitLab From d20a4dca47d2cd027ed58a13f91b424affd1f449 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 11 Jun 2008 22:03:10 +0200 Subject: [PATCH 2422/2509] 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 --- drivers/char/apm-emulation.c | 346 +++++++++++++++++++++-------------- 1 file changed, 207 insertions(+), 139 deletions(-) diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index da8a1658a27..aaca40283be 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -58,6 +58,55 @@ struct apm_queue { apm_event_t events[APM_MAX_EVENTS]; }; +/* + * 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 */ @@ -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); -- GitLab From ebb12db51f6c13b30752fcf506baad4c617b153c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Jun 2008 22:04:29 +0200 Subject: [PATCH 2423/2509] 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 --- include/linux/freezer.h | 10 +++++ include/linux/sched.h | 1 + kernel/kthread.c | 2 +- kernel/power/process.c | 97 ++++++++++++++++++----------------------- 4 files changed, 54 insertions(+), 56 deletions(-) diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 08934995c7a..deddeedf325 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -127,6 +127,15 @@ static inline void set_freezable(void) current->flags &= ~PF_NOFREEZE; } +/* + * 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 21349173d14..ba2f859c6e4 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 97747cdd37c..ac3fb732664 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 f1d0b345c9b..5fb87652f21 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"); } -- GitLab From 52d11025dba32bed696eaee1822b26529e764770 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 11 Jun 2008 22:07:52 +0200 Subject: [PATCH 2424/2509] 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 --- kernel/power/user.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index f5512cb3aa8..658262b1599 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 = { -- GitLab From 25f2f3daadaf0768a61d02ee3ed3d9a21e9dc46c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Jun 2008 22:09:45 +0200 Subject: [PATCH 2425/2509] 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 --- kernel/power/user.c | 68 ++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index 658262b1599..a6332a31326 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; } -- GitLab From c735ab7da3414c3e639d5c5223092b74689e5d87 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Jun 2008 22:27:21 -0400 Subject: [PATCH 2426/2509] 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 --- drivers/misc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0551d95a749..1921b8dbb24 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: -- GitLab From f3454ae8104efb2dbf0d08ec42c6f5d0fe9225bc Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:25:42 +0800 Subject: [PATCH 2427/2509] 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 --- drivers/acpi/namespace/nseval.c | 35 +++++++++++++++++++++++++++++++++ include/acpi/acexcep.h | 6 ++++-- include/acpi/acstruct.h | 1 + 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 14bdfa92bea..d369164e00b 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 1f591171bf3..ea627ed2420 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 a907c67d651..1cc74504f1c 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; -- GitLab From c91d924e3af08d4f98eab6ebf81f2b8ce132448f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:38:10 +0800 Subject: [PATCH 2428/2509] 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 --- drivers/acpi/dispatcher/dsmethod.c | 1 - drivers/acpi/dispatcher/dswstate.c | 10 ++-------- drivers/acpi/events/evgpe.c | 4 ---- drivers/acpi/events/evregion.c | 1 - drivers/acpi/namespace/nsinit.c | 1 - drivers/acpi/namespace/nsxfeval.c | 1 - drivers/acpi/parser/psxface.c | 2 +- drivers/acpi/resources/rsutils.c | 1 - drivers/acpi/utilities/uteval.c | 1 - include/acpi/acstruct.h | 7 ------- 10 files changed, 3 insertions(+), 26 deletions(-) diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 2509809a36c..4613b9ca579 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 1386ced332e..bda23ed6064 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 e0339d4139a..ca356e5ae2c 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 1628f593475..5ab4c01417d 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 6d6d930c8e1..e4c57510d79 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 a8d549187c8..b4e135eab7c 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 52581454c47..5ee09e1245e 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 befe2302f41..90ed83d0537 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 05e61be267d..7f1f6341242 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 1cc74504f1c..818c24d7d2d 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 -- GitLab From 6719561f9b4281491f58ed9f0bbc179dc7db95b7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 10 Jun 2008 12:49:56 +0800 Subject: [PATCH 2429/2509] 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 --- include/acpi/acmacros.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index fb41a3b802f..5ad6e399230 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 */ -- GitLab From 11f2a61ab418305167f9a3f3a31a50449222f64b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:53:01 +0800 Subject: [PATCH 2430/2509] 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 --- drivers/acpi/utilities/utmisc.c | 14 +++++--------- include/acpi/acexcep.h | 4 ++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 1f057b71db1..47354d9b0e5 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 ea627ed2420..e5a890ffeb0 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", -- GitLab From 67a119f990063f5662574f6d6414fe9bc5ece86a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:42:13 +0800 Subject: [PATCH 2431/2509] 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 --- drivers/acpi/bus.c | 2 +- drivers/acpi/dispatcher/dsinit.c | 2 +- drivers/acpi/dispatcher/dsopcode.c | 2 +- drivers/acpi/dispatcher/dswstate.c | 10 +++++----- drivers/acpi/events/evevent.c | 6 +++--- drivers/acpi/events/evgpe.c | 14 ++++---------- drivers/acpi/events/evgpeblk.c | 18 ++++++++++-------- drivers/acpi/events/evmisc.c | 4 ++-- drivers/acpi/events/evregion.c | 4 ++-- drivers/acpi/events/evrgnini.c | 2 +- drivers/acpi/executer/exconfig.c | 17 +++++++++-------- drivers/acpi/executer/exconvrt.c | 12 ++++++------ drivers/acpi/executer/exdump.c | 2 +- drivers/acpi/executer/exfldio.c | 9 +++++---- drivers/acpi/executer/exmisc.c | 8 ++++---- drivers/acpi/executer/exregion.c | 2 +- drivers/acpi/namespace/nsdump.c | 2 +- drivers/acpi/namespace/nsload.c | 3 +-- drivers/acpi/namespace/nsparse.c | 15 +++++++-------- drivers/acpi/namespace/nsutils.c | 26 ++++++++++++-------------- drivers/acpi/namespace/nsxfeval.c | 2 +- drivers/acpi/parser/psargs.c | 4 ++-- drivers/acpi/parser/psxface.c | 2 +- drivers/acpi/resources/rscalc.c | 4 ++-- drivers/acpi/resources/rsmisc.c | 2 +- drivers/acpi/resources/rsutils.c | 12 ++++++------ drivers/acpi/tables/tbfadt.c | 6 +++--- drivers/acpi/tables/tbfind.c | 5 ++--- drivers/acpi/tables/tbinstal.c | 30 ++++++++++++++---------------- drivers/acpi/tables/tbutils.c | 15 +++++++-------- drivers/acpi/tables/tbxface.c | 28 +++++++++++++--------------- drivers/acpi/tables/tbxfroot.c | 4 ++-- drivers/acpi/utilities/utcopy.c | 4 ++-- drivers/acpi/utilities/utdebug.c | 28 +++++++++++++++++----------- drivers/acpi/utilities/utdelete.c | 2 +- drivers/acpi/utilities/uteval.c | 4 ++-- drivers/acpi/utilities/utmisc.c | 14 +++++++------- drivers/acpi/utilities/utobject.c | 4 ++-- include/acpi/acdispat.h | 2 +- include/acpi/acglobal.h | 2 +- include/acpi/acmacros.h | 24 ++++++++++++------------ include/acpi/acnamesp.h | 10 ++++------ include/acpi/acpiosxf.h | 2 +- include/acpi/acpixf.h | 8 ++++---- include/acpi/acstruct.h | 2 +- include/acpi/actables.h | 27 ++++++++++++--------------- include/acpi/actypes.h | 16 ++++++---------- include/acpi/acutils.h | 4 ++-- 48 files changed, 206 insertions(+), 221 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a6dbcf4d9ef..afb34387d5f 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 610b1ee102b..949f7c75029 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 a818e0ddb99..ac0bfb1b16f 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 bda23ed6064..b00d4af791a 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 5d30e5be1b1..c56c5c6ea77 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 ca356e5ae2c..c5e53aae86f 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 e6c4d4c49e7..73c058e2f5c 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 2113e58e222..1d5670be729 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 5ab4c01417d..236fbd1ca43 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 2e3d2c5e4f4..6b94b38df07 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 39d74219058..2a32c843cb4 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 fd954b4ed83..261d97516d9 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 74f1b22601b..976016fda66 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 e336b5dc7a5..9ff9d1f4615 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 cc956a5b526..731414a581a 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 7cd8bb54fa0..7a41c409ae4 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 5445751b8a3..904f9510c0e 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 2c92f6cf5ce..a4a412b7c02 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 46a79b0103b..a82271a9dbb 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 64c039843ed..5b5619c5459 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 b4e135eab7c..38be5865d95 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 e9446377884..d830b29b85b 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 5ee09e1245e..270469aae84 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 8a112d11d49..f61ebc679e6 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 de1ac3881b2..96a6c035325 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 90ed83d0537..f7b3bcd59ba 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 949d4114eb9..a4a41ba2484 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 9ca3afc98c8..531584defbb 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 5336ce88f89..b22185f55a1 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 bc019b9b6a6..0cc92ef5236 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 0e319604d3e..fd7770aa106 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 b8c0dfa084f..2d157e0f98d 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 655c290aca7..53499ac9098 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 f938f465efa..3919fe599f9 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 1fbc35139e8..c5c791a575c 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 7f1f6341242..352747e49c7 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 47354d9b0e5..6175ca5d73b 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 e68466de804..ede6a80837d 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 910f018d92c..21a73a105d0 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 74ad971241d..15dda46b70d 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 5ad6e399230..d0494ea74b2 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 713b30903fe..d622c309002 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 d4a560d2deb..3f93a6b4e17 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 2c3806e6546..bd95ecc6e0f 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 818c24d7d2d..7980a26bad3 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 4b36a55b0b3..0cbe1b9ab52 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 dfea2d44048..4ea4f40bf89 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 b42cadf0730..3f663a0077b 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); -- GitLab From d97b4358da9bdaee5789c85415d770e36aebca52 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:43:34 +0800 Subject: [PATCH 2432/2509] 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 --- drivers/acpi/executer/excreate.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 60e62c4f057..ad09696d506 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") -- GitLab From b52437641edf63cee2f2f73a189154989b4a7ff4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:44:48 +0800 Subject: [PATCH 2433/2509] 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 --- drivers/acpi/executer/exprep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 3a2f8cd4c62..5d438c32989 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; -- GitLab From 4b8ed631679070c183c8ae7519d2bdb9df124ae4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:55:53 +0800 Subject: [PATCH 2434/2509] 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 --- drivers/acpi/executer/exdump.c | 5 ++- drivers/acpi/namespace/nsutils.c | 24 +++++------ drivers/acpi/utilities/utalloc.c | 5 ++- drivers/acpi/utilities/utdebug.c | 26 +++++++----- drivers/acpi/utilities/utmisc.c | 11 +++--- drivers/acpi/utilities/utobject.c | 5 ++- include/acpi/acinterp.h | 5 ++- include/acpi/aclocal.h | 4 +- include/acpi/acmacros.h | 2 +- include/acpi/acnamesp.h | 20 +++++----- include/acpi/acutils.h | 66 ++++++++++++++++++------------- 11 files changed, 99 insertions(+), 74 deletions(-) diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 976016fda66..c94638dc42e 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 5b5619c5459..b0817e1127b 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 ede084829a7..3dfb8a442b2 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 3919fe599f9..fd66ecb6741 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 6175ca5d73b..f34be677355 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 ede6a80837d..e25484495e6 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 e249ce5d330..accd1208dfe 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 62d7468ed3f..b221c8583dd 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 d0494ea74b2..77439df4632 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 d622c309002..9ed70a05058 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 3f663a0077b..69f8888771f 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, -- GitLab From b25d2a470bc9ffef4c34248952d914bd6fc0fcf6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:15:05 +0800 Subject: [PATCH 2435/2509] 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 --- include/acpi/acconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 28fe8bae103..f81ba6041d3 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, -- GitLab From d0e184abc5983281ef189db2c759d65d56eb1b80 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:16:47 +0800 Subject: [PATCH 2436/2509] 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 --- drivers/acpi/resources/rscreate.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index faddaee1bc0..70c84ece87f 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -284,6 +284,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 -- GitLab From 19d0cfe9ddfdf7afa8d1765ab0bd2a7dd30e47c9 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 15:54:40 +0800 Subject: [PATCH 2437/2509] 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 --- arch/x86/mm/srat_32.c | 3 +-- drivers/acpi/numa.c | 4 ++-- include/acpi/actbl1.h | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c index f41d67f8f83..1eb2973a301 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 658e5f3abae..cb9864e39ba 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 9af239bd115..dfb0fb577d9 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 */ -- GitLab From 75e5b5fb778646a93d98adb1ca697435362d2856 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:19:32 +0800 Subject: [PATCH 2438/2509] 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 --- include/acpi/acdisasm.h | 1 + include/acpi/actbl1.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 788f8878201..f53faca8ec8 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 dfb0fb577d9..d38f9be2f6e 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 { -- GitLab From 5a1a57efeb152d6b8a3b2a20f6b192d074e919ec Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:21:05 +0800 Subject: [PATCH 2439/2509] 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 --- drivers/acpi/executer/exdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index c94638dc42e..f337c3f73e0 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); -- GitLab From 71d993e115706a4108bdc7e3cb3cf25309f17aa6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:25:05 +0800 Subject: [PATCH 2440/2509] 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 --- drivers/acpi/dispatcher/dsopcode.c | 20 +-------- drivers/acpi/dispatcher/dswexec.c | 8 ---- drivers/acpi/executer/exdump.c | 68 ++++++++++++------------------ drivers/acpi/executer/exresop.c | 4 ++ drivers/acpi/executer/exstore.c | 6 --- drivers/acpi/namespace/nsdump.c | 4 +- include/acpi/acinterp.h | 6 +-- include/acpi/acmacros.h | 4 +- 8 files changed, 37 insertions(+), 83 deletions(-) diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index ac0bfb1b16f..6a81c4400ed 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 b246b9657ea..b5072fa9c92 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 f337c3f73e0..2be2e2bf95b 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 73e29e566a7..54085f16ec2 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 76c875bc315..38b55e35249 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 904f9510c0e..0ab22004728 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 accd1208dfe..e8db7a3143a 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 77439df4632..57ab9e9d759 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) -- GitLab From fd0a43276dc986e186eb27e5755a18e97e07a7eb Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:27:55 +0800 Subject: [PATCH 2441/2509] 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 --- drivers/acpi/resources/rscreate.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 70c84ece87f..7804a8c40e7 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++; -- GitLab From b53ce3f7186e2fc561f02085b5021df10d715ce2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:30:04 +0800 Subject: [PATCH 2442/2509] 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 --- drivers/acpi/utilities/utmutex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index f7d602b1a89..7331dde9e1b 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; -- GitLab From 9c9f6d052dc6f469431461a97d49cf9c5558b8ad Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:37:53 +0800 Subject: [PATCH 2443/2509] ACPICA: Update version to 20080609 Update version to 20080609. Signed-off-by: Len Brown Signed-off-by: Andi Kleen --- include/acpi/acconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index f81ba6041d3..4eb75a88795 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, -- GitLab From 71b58cbb0c30d1f78636a48c4721529449d6ea37 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 20 Jun 2008 09:42:47 +0800 Subject: [PATCH 2444/2509] 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 --- Documentation/ABI/testing/sysfs-firmware-acpi | 127 ++++++++----- drivers/acpi/events/evxfevnt.c | 18 +- drivers/acpi/hardware/hwgpe.c | 2 - drivers/acpi/system.c | 169 ++++++++++++++++-- include/acpi/achware.h | 2 - include/acpi/acpixf.h | 4 - 6 files changed, 258 insertions(+), 64 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi index 9470ed9afcc..f27be7d1a49 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 99a7502e6a8..73bfd6bf962 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 58347d6c43f..0b80db9d919 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 5bd2dec9a7a..d8e3f153b29 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 45e985961f4..97a72b19327 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 bd95ecc6e0f..94d94e126e9 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, -- GitLab From 5b53496a5ad79e91052f72761a7c5516b069bc99 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 17 Jun 2008 14:39:59 +0800 Subject: [PATCH 2445/2509] 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 --- arch/x86/kernel/acpi/processor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index de2d2e4ebad..7c074eec39f 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; -- GitLab From c1e3b377ad48febba6f91b8ae42c44ee4d4ab45e Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 17:58:53 +0800 Subject: [PATCH 2446/2509] 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 --- Documentation/kernel-parameters.txt | 4 +++- arch/ia64/kernel/process.c | 2 ++ arch/x86/kernel/process.c | 17 ++++++++++++++++- drivers/acpi/processor_idle.c | 22 ++++++++++++++++++++++ include/asm-ia64/processor.h | 1 + include/asm-x86/processor.h | 1 + 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 312fe77764a..65db7f4711a 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 fabaf08d9a6..612b3c4a060 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 7dceea94723..7fc72949876 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 0fc310e7dfd..c75c7ace8c1 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 6aff126fc07..f36e28a5f61 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 7f738270459..bc221623248 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); -- GitLab From da5e09a1b3e5a9fc0b15a3feb64e921ccc55ba74 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 18:01:09 +0800 Subject: [PATCH 2447/2509] 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 --- Documentation/kernel-parameters.txt | 3 ++- arch/ia64/kernel/process.c | 2 ++ arch/x86/kernel/process.c | 11 +++++++++++ drivers/acpi/processor_core.c | 13 +++++++++++++ drivers/acpi/processor_idle.c | 6 +++++- include/asm-ia64/processor.h | 1 + include/asm-x86/processor.h | 1 + 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 65db7f4711a..5e497d16fb5 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 612b3c4a060..3ab8373103e 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 7fc72949876..4d629c62f4f 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 9a803f85ccf..4e1bb89fd6c 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 c75c7ace8c1..d592dbb1d12 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 f36e28a5f61..f88fa054d01 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 bc221623248..55402d2ab93 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); -- GitLab From 2a2a64714d9c40f7705c4de1e79a5b855c7211a9 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 18:02:57 +0800 Subject: [PATCH 2448/2509] 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 --- drivers/acpi/processor_core.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4e1bb89fd6c..ec0f2d581ec 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; -- GitLab From 65573ee72e34e767a135a0841ac5380a2be1a390 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 Jun 2008 11:22:46 -0400 Subject: [PATCH 2449/2509] 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 --- MAINTAINERS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ec5c8ee3090..4e49e9c8195 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/ -- GitLab From 8aa863b8ca0855378e3409b5e55ad57a856f6412 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 Jun 2008 11:31:50 -0400 Subject: [PATCH 2450/2509] 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 --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4e49e9c8195..633bda666e4 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/ -- GitLab From 469778c1740fcf3113498b6fdf4559bdec25c58f Mon Sep 17 00:00:00 2001 From: Julia Jomantaite Date: Mon, 23 Jun 2008 22:50:42 +0100 Subject: [PATCH 2451/2509] 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 --- drivers/acpi/video.c | 123 +++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d089c4519d4..64c889331f3 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); -- GitLab From b897f46cf7941fff8130ccdaf85f39528bff6a51 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:52 -0600 Subject: [PATCH 2452/2509] 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 --- drivers/pnp/support.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 95b076c18c0..7f594ccf495 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 } -- GitLab From 87e4acf3ebc02c9d0a2f7a37b655c49176c4d765 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:53 -0600 Subject: [PATCH 2453/2509] 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 --- drivers/pnp/base.h | 1 - drivers/pnp/interface.c | 20 ++-------- drivers/pnp/isapnp/core.c | 84 ++++++++++++++------------------------- drivers/pnp/manager.c | 4 -- 4 files changed, 33 insertions(+), 76 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 886dac823ed..6f60097c421 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 5695a79f3a5..3f8007ab94e 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 f1bccdbdeb0..752b51fbaa6 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 bea0914ff94..90bd9cb6556 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; -- GitLab From 940e98dbc616f1df7b63b73858a966969baf261d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:54 -0600 Subject: [PATCH 2454/2509] 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 --- drivers/pnp/base.h | 1 + drivers/pnp/resource.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 6f60097c421..4c2a6256499 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 390b50096e3..cce341f743d 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) { -- GitLab From 9fdee4e02e3b214cde8e4f3beb6776075a3d08a7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:55 -0600 Subject: [PATCH 2455/2509] 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 --- drivers/pnp/base.h | 1 + drivers/pnp/support.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 4c2a6256499..c91315826da 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 7f594ccf495..eb07345f5cf 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 -- GitLab From 20bfdbba7212d19613b93dcea93f26cb65af91fe Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:56 -0600 Subject: [PATCH 2456/2509] 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 --- include/linux/pnp.h | 72 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 63b128d512f..8b607aecd95 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) -- GitLab From aee3ad815dd291a7193ab01da0f1a30c84d00061 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:57 -0600 Subject: [PATCH 2457/2509] 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 --- drivers/pnp/base.h | 18 +-- drivers/pnp/core.c | 25 ++-- drivers/pnp/interface.c | 60 ++++----- drivers/pnp/isapnp/core.c | 12 +- drivers/pnp/manager.c | 220 +++++++++------------------------ drivers/pnp/pnpacpi/rsparser.c | 131 +++++++++++++------- drivers/pnp/pnpbios/rsparser.c | 95 ++++++++++---- drivers/pnp/quirks.c | 3 +- drivers/pnp/resource.c | 86 +++---------- drivers/pnp/support.c | 79 ++++++------ drivers/pnp/system.c | 4 +- include/linux/pnp.h | 20 +-- 12 files changed, 331 insertions(+), 422 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index c91315826da..1667ac3ca45 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 20771b7d448..7182da92aec 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 3f8007ab94e..7fc86bbed88 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 752b51fbaa6..ca4457ec403 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 90bd9cb6556..165b624081a 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 46c791adb89..9a45c25b46d 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 5ff9a4c0447..01f0c3dd1b0 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 1ff3bb585ab..21acb54eff6 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 cce341f743d..0797a77bd04 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 eb07345f5cf..1566e4a7384 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 cf4e07b01d4..764f3a31068 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 8b607aecd95..dfaa567e04a 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 */ -- GitLab From 5acf91415799025410cc0d13101340d352f34c89 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:58 -0600 Subject: [PATCH 2458/2509] 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 --- drivers/pnp/pnpacpi/rsparser.c | 70 +++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 9a45c25b46d..595252b6520 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; -- GitLab From 25d39c39d82d062f4be685146abd054a3bafdf12 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:59 -0600 Subject: [PATCH 2459/2509] 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 --- drivers/pnp/resource.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 0797a77bd04..ff79aa6168c 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; } -- GitLab From f61ed7e32d2d6a0a8c3c101da513ccedd542e14d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:00 -0600 Subject: [PATCH 2460/2509] 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 --- drivers/pnp/interface.c | 56 ++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 7fc86bbed88..674e8ba0377 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; -- GitLab From 57fd51a8be26921b56747ddd09d1d9e01c11c9e0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:01 -0600 Subject: [PATCH 2461/2509] 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 --- drivers/pnp/resource.c | 62 +++++++++++++++++++++++++++++++++++++++ drivers/serial/8250_pnp.c | 24 +++++---------- include/linux/pnp.h | 5 ++++ 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index ff79aa6168c..786fd356916 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 97c68d021d2..638b68649e7 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 dfaa567e04a..e033e1b14c2 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; } -- GitLab From b72ee1f11e373179ec703e0e5afaf585ed3a950a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:02 -0600 Subject: [PATCH 2462/2509] 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 --- drivers/pnp/interface.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 674e8ba0377..239923a300c 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; -- GitLab From 08c9f262f268f7948be13bf3a5bda1d635c649b4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:03 -0600 Subject: [PATCH 2463/2509] 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 --- drivers/pnp/interface.c | 2 +- drivers/pnp/isapnp/core.c | 4 ++-- drivers/pnp/pnpacpi/rsparser.c | 10 +++++----- drivers/pnp/pnpbios/rsparser.c | 4 ++-- include/linux/ioport.h | 4 ++++ include/linux/pnp.h | 3 --- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 239923a300c..c172b6de6b7 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 ca4457ec403..c5b92526963 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 595252b6520..46069e64a6b 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 01f0c3dd1b0..489fec3b797 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 c6801bffe76..39db059ffb8 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 e033e1b14c2..e1454dabde1 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 */ -- GitLab From a1802c42950403657d07e64558eff612d550ce16 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:04 -0600 Subject: [PATCH 2464/2509] 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 --- drivers/pnp/base.h | 48 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pnp.h | 48 --------------------------------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 1667ac3ca45..3126e458200 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 e1454dabde1..785126ffcc1 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 */ -- GitLab From 7aefff51854ccd33599c40b4e360d94cb2b7622f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:05 -0600 Subject: [PATCH 2465/2509] 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 --- drivers/pnp/base.h | 4 +++- drivers/pnp/interface.c | 4 ++-- drivers/pnp/isapnp/core.c | 2 +- drivers/pnp/manager.c | 6 +++--- drivers/pnp/pnpacpi/rsparser.c | 4 ++-- drivers/pnp/pnpbios/rsparser.c | 2 +- drivers/pnp/quirks.c | 11 +++++++---- drivers/pnp/resource.c | 6 +++--- 8 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 3126e458200..a9ee0a9fec7 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 c172b6de6b7..249b4078d1e 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 c5b92526963..e0caa71b16c 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 165b624081a..e758dd22557 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 46069e64a6b..ae65454a23b 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 489fec3b797..dd2ea7b0360 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 21acb54eff6..48e60171b3b 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 786fd356916..55a57cded24 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; -- GitLab From 169aaffe885c56745188e7913f212a67beaa3b80 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:06 -0600 Subject: [PATCH 2466/2509] 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 --- drivers/pnp/base.h | 16 ++++++++-------- drivers/pnp/interface.c | 17 +++++++++++------ drivers/pnp/resource.c | 14 ++++++++++---- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index a9ee0a9fec7..afbeee5b8af 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 249b4078d1e..b09f67de13d 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 55a57cded24..391828c7f20 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; } -- GitLab From fcfb7ce3d688d5c15fc9bc0a2a48e1ededdb046f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:07 -0600 Subject: [PATCH 2467/2509] 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 --- drivers/pnp/manager.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index e758dd22557..c706dd2ddb0 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; } } -- GitLab From 819beac3806a5e986d81f476b999b7fffce1a233 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:08 -0600 Subject: [PATCH 2468/2509] 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 --- drivers/pnp/support.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 1566e4a7384..0ad42db9488 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; -- GitLab From 6e906f0e1c8633ed357a64e9861f1822789bee3d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:09 -0600 Subject: [PATCH 2469/2509] 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 --- drivers/pnp/manager.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c706dd2ddb0..1adc83fdabb 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; } -- GitLab From b08395e5038e3337bb85c7246a635a3be6d5a29c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:10 -0600 Subject: [PATCH 2470/2509] 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 --- drivers/pnp/manager.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 1adc83fdabb..7ea9e1e2800 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); -- GitLab From c227536b4cc2600fc9d22ba0067f699165f6621f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:11 -0600 Subject: [PATCH 2471/2509] 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 --- drivers/pnp/base.h | 12 ++- drivers/pnp/isapnp/core.c | 112 ++++++++++--------------- drivers/pnp/pnpacpi/rsparser.c | 149 +++++++++++---------------------- drivers/pnp/pnpbios/rsparser.c | 120 +++++++++++--------------- drivers/pnp/resource.c | 54 ++++++++++-- 5 files changed, 198 insertions(+), 249 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index afbeee5b8af..360c6385686 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 e0caa71b16c..3f75fdbe609 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 ae65454a23b..3aaf406b67b 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 dd2ea7b0360..26fb04cc12b 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 391828c7f20..61145491f36 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) -- GitLab From fe2cf598e6942abd8fb70fee230d74b1a1eae0d1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:12 -0600 Subject: [PATCH 2472/2509] 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 --- drivers/pnp/pnpacpi/rsparser.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3aaf406b67b..851c773feae 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); -- GitLab From 2d29a7a794c5bae982955cd5dd0a76e766e57f39 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:13 -0600 Subject: [PATCH 2473/2509] 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 --- drivers/pnp/resource.c | 94 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 61145491f36..a795864dc69 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; } -- GitLab From d5ebde6ef5c2d51828f975a81d7d0e58bccfd833 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:14 -0600 Subject: [PATCH 2474/2509] 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 --- drivers/pnp/interface.c | 2 ++ drivers/pnp/manager.c | 9 ++++++ drivers/pnp/quirks.c | 71 ++++++++++++++++------------------------- include/linux/ioport.h | 1 + 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index b09f67de13d..7a9fb5544b8 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 7ea9e1e2800..a20accb5ef8 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 48e60171b3b..e8515ce0d29 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 39db059ffb8..2cd07cc2968 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) -- GitLab From e2a1a6f1cfaf6ee770a8700e5df8a3708dae503b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:15 -0600 Subject: [PATCH 2475/2509] 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 --- drivers/pnp/isapnp/core.c | 8 +++----- drivers/pnp/pnpacpi/rsparser.c | 2 +- drivers/pnp/pnpbios/rsparser.c | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 3f75fdbe609..90718be6646 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 851c773feae..e114b3d2b93 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 26fb04cc12b..db23ba78d39 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; -- GitLab From bbe413b4fc7f791248c7ee00ce7b3778491a3700 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:16 -0600 Subject: [PATCH 2476/2509] 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 --- drivers/pnp/isapnp/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 90718be6646..53cc4d6133e 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: -- GitLab From 1f32ca31e7409d37c1b25e5f81840fb184380cdf Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:17 -0600 Subject: [PATCH 2477/2509] 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 --- drivers/pnp/base.h | 93 ++++++++--- drivers/pnp/core.c | 4 +- drivers/pnp/interface.c | 75 ++++----- drivers/pnp/isapnp/core.c | 72 ++++---- drivers/pnp/manager.c | 145 ++++++----------- drivers/pnp/pnpacpi/rsparser.c | 93 +++++------ drivers/pnp/pnpbios/rsparser.c | 67 ++++---- drivers/pnp/quirks.c | 290 ++++++++++++++++++--------------- drivers/pnp/resource.c | 268 ++++++++---------------------- drivers/pnp/support.c | 92 +++++++++++ include/linux/pnp.h | 6 +- 11 files changed, 571 insertions(+), 634 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 360c6385686..e3fa9a2d9a3 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 7182da92aec..a411582bcd7 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 7a9fb5544b8..a876ecf7028 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 53cc4d6133e..101a835e875 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 a20accb5ef8..b526eaad3f6 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 e114b3d2b93..c2f59f4d20b 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 db23ba78d39..ca567671379 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 e8515ce0d29..55f55ed72dc 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 a795864dc69..d6388970a1a 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 0ad42db9488..bbf78ef4ba0 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 785126ffcc1..1ce54b63085 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 */ -- GitLab From 84684c7469a2e6fcbf8c808ac5030ba2de14ff77 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:18 -0600 Subject: [PATCH 2478/2509] 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 --- drivers/pnp/resource.c | 68 +++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index d6388970a1a..4cfe3a1efdf 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 */ -- GitLab From 40ab4f4c1d843362eb26d83425317e91fbd98b17 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:19 -0600 Subject: [PATCH 2479/2509] 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 --- drivers/pnp/pnpacpi/rsparser.c | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c2f59f4d20b..d7e9f2152df 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: -- GitLab From c83642d5123225a22cccd75adea6e97c245714cb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 08:45:39 -0600 Subject: [PATCH 2480/2509] 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 --- drivers/acpi/pci_irq.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 89022a74fae..11acaee14d6 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; } -- GitLab From 4d3870431d17346c4fdd80e087b7d76f1b5941d5 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Wed, 16 Jul 2008 23:27:08 +0200 Subject: [PATCH 2481/2509] 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 --- drivers/acpi/Makefile | 2 +- drivers/acpi/reboot.c | 50 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/reboot.h | 14 ++++++------ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 drivers/acpi/reboot.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 40b0fcae4c7..4efbe598c81 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 00000000000..a6b662c00b6 --- /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 8857f57e0b7..0419184ce88 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 -- GitLab From 01a5bba576b9364b33f61f0cd9fa70c2cf5535e2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 16 Jul 2008 23:27:08 +0200 Subject: [PATCH 2482/2509] 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 --- drivers/acpi/tables/tbfadt.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index a4a41ba2484..ccb5b64bbef 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; } } -- GitLab From d442cc44c0db56e84ef6aa244a88427d2efe06cd Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 16 Jul 2008 16:09:06 -0400 Subject: [PATCH 2483/2509] 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 --- include/linux/blkdev.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 32a441b05fd..88d68081a0f 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); } -- GitLab From c0420ad2ca514551ca086510b0e7d17a05c70492 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Mon, 30 Jun 2008 18:45:45 +0800 Subject: [PATCH 2484/2509] [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 --- fs/ocfs2/aops.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 17964c0505a..1db080135c6 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)) -- GitLab From 58b6e5538460be358fdf1286d9a2fbcfcc2cfaba Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 16 Jul 2008 16:21:47 -0700 Subject: [PATCH 2485/2509] 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. --- arch/x86/pci/acpi.c | 80 --------------------------------------------- 1 file changed, 80 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d1ffb570917..d95de2f199c 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; } -- GitLab From 33af79d12e0fa25545d49e86afc67ea8ad5f2f40 Mon Sep 17 00:00:00 2001 From: Chandra Seetharaman Date: Wed, 16 Jul 2008 17:35:08 -0700 Subject: [PATCH 2486/2509] 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 --- drivers/scsi/device_handler/scsi_dh_emc.c | 7 ++++++- drivers/scsi/device_handler/scsi_dh_hp_sw.c | 7 ++++++- drivers/scsi/device_handler/scsi_dh_rdac.c | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index ed53f14007a..f2467e936e5 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 12ceab7b366..ae6be87d6a8 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 6fff077a888..fdf34b0ec6e 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, -- GitLab From 98abed02007b19bbfd68b6d06a5485afc3eeb01b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 19 Mar 2008 19:24:59 -0700 Subject: [PATCH 2487/2509] 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 --- kernel/exit.c | 215 +++++++++++++++++++++++++++++++------------------- 1 file changed, 135 insertions(+), 80 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index ceb25878283..7453356a961 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); -- GitLab From f470021adb9190819c03d6d8c5c860a17480aa6d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 24 Mar 2008 18:36:23 -0700 Subject: [PATCH 2488/2509] 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 --- include/linux/init_task.h | 4 +- include/linux/sched.h | 26 ++--- kernel/exit.c | 226 ++++++++++++++++++++------------------ kernel/fork.c | 6 +- kernel/ptrace.c | 37 ++++--- 5 files changed, 160 insertions(+), 139 deletions(-) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 9927a88674a..93c45acf249 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 ba2f859c6e4..1941d8b5cf1 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 7453356a961..1e909826a80 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 4bd2f516401..adefc1131f2 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 e337390fce0..8392a9da645 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; -- GitLab From 14dd0b81414a58caf0296dbeace016bb0a5d11ab Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 30 Mar 2008 18:41:25 -0700 Subject: [PATCH 2489/2509] 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 --- kernel/exit.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 1e909826a80..a2af6cac823 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, -- GitLab From 666f164f4fbfa78bd00fb4b74788b42a39842c64 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 8 Apr 2008 23:12:30 -0700 Subject: [PATCH 2490/2509] 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 --- kernel/exit.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/exit.c b/kernel/exit.c index a2af6cac823..93d2711b938 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -702,6 +702,23 @@ static void exit_mm(struct task_struct * tsk) mmput(mm); } +/* + * 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)) { -- GitLab From 8e9509c827a28e2f365c203c04224f9e9dd1b63a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 13:26:50 +0200 Subject: [PATCH 2491/2509] 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 --- arch/x86/kernel/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 5112c84f542..da140611bb5 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 -- GitLab From 12e0c95e0ca99f633c9d9f90773037eb178685ad Mon Sep 17 00:00:00 2001 From: Frank Munzert Date: Thu, 17 Jul 2008 17:16:40 +0200 Subject: [PATCH 2492/2509] [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 --- drivers/s390/char/zcore.c | 101 +++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 047dd92ae80..7fd84be1193 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; -- GitLab From 9d853caf44e6f969a9ad056a9937e8d97bc2c761 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 17 Jul 2008 17:16:41 +0200 Subject: [PATCH 2493/2509] [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 --- drivers/s390/block/dasd_eckd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index e0b77210d37..3590fdb5b2f 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; } -- GitLab From 626f311737770f0fb5c09a6da2ea795a559aa42a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 17:16:42 +0200 Subject: [PATCH 2494/2509] [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 --- include/asm-s390/Kbuild | 2 +- include/asm-s390/chpid.h | 6 +++--- include/asm-s390/schid.h | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild index 09f312501eb..bb5e9edb982 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 606844d0a5c..dfe3c7f3439 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 5017ffa78e0..7bdc0fe1569 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 */ -- GitLab From 7337194f708bac977511c7890d7038ded187041a Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 17 Jul 2008 17:16:43 +0200 Subject: [PATCH 2495/2509] [S390] dasd: Fix cleanup in dasd_{fba,diag}_check_characteristics(). Signed-off-by: Cornelia Huck Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky --- drivers/s390/block/dasd_diag.c | 25 ++++++++++++++++++------- drivers/s390/block/dasd_fba.c | 7 ++++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index d91df38ee4f..ab5c5b43bdc 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 aee4656127f..aa0c533423a 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; } -- GitLab From c5a37255493a3a8bf527534c8700dd73bd591fc7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 17 Jul 2008 17:16:44 +0200 Subject: [PATCH 2496/2509] [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 --- arch/s390/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dc8f8028d5..eb530b4128b 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. -- GitLab From 8de2ce86cdde64d00fc4a4034008b35d8fc0dc83 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 17 Jul 2008 17:16:45 +0200 Subject: [PATCH 2497/2509] [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 --- arch/s390/kernel/stacktrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 57571f10270..8841919ef7e 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, -- GitLab From b9993a38a9b491a9df48a5bc82d2e03ab44e352a Mon Sep 17 00:00:00 2001 From: Frank Munzert Date: Thu, 17 Jul 2008 17:16:46 +0200 Subject: [PATCH 2498/2509] [S390] vmur: Fix return code handling. Use -EOPNOTSUPP instead of -ENOTSUPP. Signed-off-by: Frank Munzert Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky --- drivers/s390/char/vmur.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 0a9f1cccbe5..b0ac44b2712 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; } -- GitLab From dae39843f478d181da5b5e1c2c703dfcaaf838c1 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 17 Jul 2008 17:16:47 +0200 Subject: [PATCH 2499/2509] [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 --- drivers/s390/cio/chsc.c | 9 ++++++++- drivers/s390/cio/chsc.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 65264a38057..29826fdd47b 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 fb6c4d6c45b..ba59bceace9 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 -- GitLab From 779e6e1c724d30e0fd1baca78b852e41e3a23c1d Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Thu, 17 Jul 2008 17:16:48 +0200 Subject: [PATCH 2500/2509] [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 --- drivers/s390/cio/Makefile | 2 + drivers/s390/cio/qdio.c | 3929 ----------------------------- drivers/s390/cio/qdio.h | 835 +++--- drivers/s390/cio/qdio_debug.c | 240 ++ drivers/s390/cio/qdio_debug.h | 91 + drivers/s390/cio/qdio_main.c | 1755 +++++++++++++ drivers/s390/cio/qdio_perf.c | 151 ++ drivers/s390/cio/qdio_perf.h | 54 + drivers/s390/cio/qdio_setup.c | 521 ++++ drivers/s390/cio/qdio_thinint.c | 380 +++ drivers/s390/net/qeth_core.h | 12 +- drivers/s390/net/qeth_core_main.c | 87 +- drivers/s390/net/qeth_l2_main.c | 26 +- drivers/s390/net/qeth_l3_main.c | 25 +- drivers/s390/scsi/zfcp_dbf.c | 12 +- drivers/s390/scsi/zfcp_dbf.h | 2 - drivers/s390/scsi/zfcp_ext.h | 5 +- drivers/s390/scsi/zfcp_qdio.c | 42 +- include/asm-s390/qdio.h | 646 +++-- include/asm-s390/setup.h | 2 +- 20 files changed, 3874 insertions(+), 4943 deletions(-) delete mode 100644 drivers/s390/cio/qdio.c create mode 100644 drivers/s390/cio/qdio_debug.c create mode 100644 drivers/s390/cio/qdio_debug.h create mode 100644 drivers/s390/cio/qdio_main.c create mode 100644 drivers/s390/cio/qdio_perf.c create mode 100644 drivers/s390/cio/qdio_perf.h create mode 100644 drivers/s390/cio/qdio_setup.c create mode 100644 drivers/s390/cio/qdio_thinint.c diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 91e9e3f3073..bd79bd16539 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 2bf36e14b10..00000000000 --- 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 00000000000..337aa3087a7 --- /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 00000000000..8484b83698e --- /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 00000000000..d10c73cc168 --- /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 00000000000..ea01b85b1cc --- /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 00000000000..5c406a8b738 --- /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 00000000000..f0923a8aced --- /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 00000000000..9291a771d81 --- /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 699ac11debd..1895dbb553c 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 0ac54dc638c..c3ad89e302b 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 f682f7b1448..3fbc3bdec0c 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 06deaee50f6..22f64aa6dd1 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 36169c6944f..fca48b88fc5 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 d04aea60497..0ddb18449d1 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 8065b2b224b..edfdb21591f 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 72e3094796d..d6dbd653fde 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 11240342a0f..6813772171f 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 f09ee3f7297..4ba14e463e8 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__ -- GitLab From 8586cb60ce85f40431cf06fe97512269d3992f03 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 17 Jul 2008 17:16:49 +0200 Subject: [PATCH 2501/2509] [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 --- drivers/s390/block/dasd_diag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index ab5c5b43bdc..85fcb437105 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; } -- GitLab From 9fa111372a54f695f65e0de2f2a2108fe6cf3584 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 17:38:17 +0200 Subject: [PATCH 2502/2509] 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 --- lib/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Makefile b/lib/Makefile index 2c62a9c06fb..d90d31102e0 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 -- GitLab From c349e0a01c3e0f70913db6a5bb61ab204e0602de Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Apr 2008 22:39:31 +0200 Subject: [PATCH 2503/2509] 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 --- kernel/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 0a7ed838984..985ddb7da4d 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 -- GitLab From 2464a609ded094204a3aed24823745ec58e3c879 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 17:40:48 +0200 Subject: [PATCH 2504/2509] 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 --- lib/Makefile | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index d90d31102e0..818c4d45551 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 -- GitLab From 7023cc61292f9cd61d99521206480f6e387132ff Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 17 Jul 2008 01:06:55 -0600 Subject: [PATCH 2505/2509] 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 --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 1564577bdc5..6192922de9c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -FRED=42 VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -- GitLab From 7259d936c6af216198ae6af3a25ac6c9dbdbe779 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 16 Jul 2008 23:44:32 -0700 Subject: [PATCH 2506/2509] 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 --- scripts/Makefile.fwinst | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 3d2f4609578..c972c0f54ce 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 -- GitLab From 2f73ccab5628b4f8e8f4b93fea8082dd31a87a10 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Jul 2008 18:09:12 +0200 Subject: [PATCH 2507/2509] 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 --- arch/ia64/kvm/kvm-ia64.c | 4 ++-- arch/ia64/kvm/kvm_fw.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 318b8110062..68c978be9a5 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 091f936c448..0c69d9ec92d 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); -- GitLab From 9354094a95aed456a46b353b1051a7e2fab29045 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 14 Jul 2008 23:29:01 -0700 Subject: [PATCH 2508/2509] 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 --- arch/x86/kernel/numaq_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 5b20a5e7ac2..a23e8233b9a 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"); -- GitLab From 2567d71cc7acd99f0a0dd02e17fe17fd7df7b30c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Jul 2008 15:02:27 +1000 Subject: [PATCH 2509/2509] 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 --- include/asm-x86/e820.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 33e793e991d..06633b01dd5 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 -- GitLab